H2数据库数据读取问题:查询指定员工报错及PreparedStatement用法咨询
解决H2数据库查询的表不存在错误与PreparedStatement使用问题
嘿,我来帮你一步步解决代码里的问题,让你能顺利在控制台输出指定员工的信息:
首先分析你遇到的核心问题
1. "Table 'MyTable' not found" 错误(实际你代码里查的是RABOTNICI)
这个错误大概率是以下原因之一:
- 数据库里根本没有创建
RABOTNICI表:先打开H2控制台,手动执行SELECT * FROM RABOTNICI验证是否存在这个表,如果不存在需要先建表。 - 表名/字段名大小写不匹配:H2默认对标识符(表名、字段名)是大小写敏感的,如果你创建表时用了双引号(比如
CREATE TABLE "RABOTNICI"),查询时也要用双引号包裹表名;如果是小写创建的,查询也要用小写。 - 连接字符串错误导致连到了错误的数据库:这个是你代码里的明显问题,下面会详细说。
2. PreparedStatement 使用完全错误
你现在用String.format拼接SQL,完全违背了PreparedStatement预编译、防SQL注入的初衷,而且写法也不对,正确的姿势是用占位符?来绑定参数。
3. 代码里的其他顺序/语法错误
- 驱动加载顺序反了:
Class.forName("org.h2.Driver")应该在获取数据库连接之前执行。 - 连接字符串拼接错误:你把用户名直接拼到URL里了,正确的连接方式应该是把URL、用户名、密码作为三个独立参数传给
getConnection。 - 资源未关闭:Connection、PreparedStatement、ResultSet这些资源用完必须关闭,否则会造成内存泄漏。
- 没有遍历ResultSet:你获取了结果集但没有读取和输出,所以看不到查询结果。
修复后的完整代码
我把你的代码重写了,加上了try-with-resources(自动关闭资源)、正确的PreparedStatement用法,以及控制台输出逻辑:
static public void Search(JButton searchBtn, JFormattedTextField nameInput, JComboBox<String> positionCombo) { searchBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // 1. 先加载驱动(JDBC4+可以省略,但显式写更稳妥) try { Class.forName("org.h2.Driver"); } catch (ClassNotFoundException ex) { System.err.println("H2驱动加载失败: " + ex.getMessage()); return; } // 2. 使用try-with-resources自动关闭连接、PreparedStatement、ResultSet String jdbcUrl = "jdbc:h2:tcp://localhost/~/test"; String username = "sa"; String password = ""; String sql = "SELECT IME, POZICIA FROM RABOTNICI WHERE IME = ? OR POZICIA = ?"; try (Connection con = DriverManager.getConnection(jdbcUrl, username, password); PreparedStatement prstm = con.prepareStatement(sql)) { // 3. 绑定参数到PreparedStatement的占位符(索引从1开始) String targetName = nameInput.getText().trim(); String targetPosition = (String) positionCombo.getSelectedItem(); prstm.setString(1, targetName); prstm.setString(2, targetPosition); // 4. 执行查询,获取结果集 try (ResultSet rs = prstm.executeQuery()) { // 5. 遍历结果集,输出到控制台 System.out.println("查询到的员工信息:"); while (rs.next()) { String name = rs.getString("IME"); String position = rs.getString("POZICIA"); System.out.printf("姓名:%s | 职位:%s%n", name, position); } // 如果没有查到结果,提示用户 if (!rs.isBeforeFirst()) { System.out.println("没有找到符合条件的员工"); } } } catch (SQLException ex) { System.err.println("数据库操作出错: " + ex.getMessage()); ex.printStackTrace(); } } }); }
关键修改点说明
- 连接字符串修正:把URL、用户名、密码分开传递,避免拼接错误导致连错数据库。
- PreparedStatement正确用法:用
?作为占位符,通过setString绑定参数,彻底避免SQL注入风险,也解决了字符串拼接可能导致的语法错误。 - 资源自动管理:try-with-resources会在代码块结束后自动关闭所有实现了
AutoCloseable的资源(Connection、PreparedStatement、ResultSet都属于这类),不用手动写finally关闭。 - 结果集遍历输出:通过
while(rs.next())遍历每一行数据,获取指定字段的值并打印到控制台。 - 错误处理:恢复了try/catch块(这是必须的,不能省略),方便排查驱动加载、数据库连接、查询过程中的错误。
最后要做的验证步骤
- 打开H2控制台,连接到
jdbc:h2:tcp://localhost/~/test,执行SELECT * FROM RABOTNICI确认表存在,且字段IME和POZICIA正确。 - 测试代码时,输入存在的姓名或选择存在的职位,看控制台是否输出正确的信息。
内容的提问来源于stack exchange,提问作者Angel
相关产品推荐
相关产品推荐

