ResultSet.next()无法获取行:JavaDB访问toursdb数据库无输出求助
听起来你已经搞定了数据库连接,连元数据都能正常获取,结果集却空得离谱——这种情况我碰到过好几次,大概率是这几个细节没处理好:
1. 先确认你的SQL查询真的能返回数据
别先怀疑代码,先手动验证查询语句!打开Derby的命令行工具(比如ij),连接到toursdb,直接运行你代码里的SQL语句,看看有没有输出。比如:
CONNECT 'jdbc:derby:toursdb'; SELECT * FROM 你的表名;
如果这里都没数据,那代码当然查不到——要么是表本身是空的,要么是你的查询条件太苛刻(比如WHERE id = 999但根本没这个ID),或者表名/字段名大小写不匹配。Derby默认区分标识符大小写,如果你代码里写的是SELECT * FROM Tours,但实际表名是tours(小写),那肯定查不到,得改成一致的,或者用双引号包裹标识符(比如SELECT * FROM "tours")。
2. 检查ResultSet的游标操作是否正确
有没有可能你在调用rs.next()之前,不小心移动过游标?比如有些新手会先调用一次rs.next()判断,然后在循环里又调用一次,导致跳过了唯一的行。举个反例:
// 错误示例:两次调用next(),跳过第一行 if (rs.next()) { while (rs.next()) { // 这里根本不会处理第一行数据 System.out.println(rs.getString(1)); } }
正确的写法应该是直接用while循环:
// 正确写法 while (rs.next()) { System.out.println(rs.getString("列名")); }
或者如果只取一行,用if判断后直接获取数据,别再重复调用next()。
3. 排查事务提交的问题
Derby默认的事务隔离级别是READ_COMMITTED,而且默认开启自动提交(auto-commit),但如果你手动关闭了auto-commit(比如con.setAutoCommit(false)),而且之前执行过插入/更新操作但没提交,那在同一个事务里查询可能看不到最新数据。或者你刚插入数据就查询,但没提交,结果集也会是空的。
解决办法:要么确保auto-commit是开启的(con.setAutoCommit(true)),要么在修改数据后调用con.commit(),再执行查询。
4. 确认表在当前连接的Schema下
Derby的表默认会创建在APP这个schema下(如果没指定的话),但如果你连接时指定了其他schema,或者表是在别的schema里创建的,直接写表名会找不到。比如表在USER1.Tours里,你得写SELECT * FROM USER1.Tours,或者在连接URL里指定schema:jdbc:derby:toursdb;user=USER1。
你可以用con.getMetaData().getUserName()查看当前连接的用户名(也就是默认schema),再对比表所在的schema。
最后再检查资源释放的时机
有没有可能你在调用rs.next()之前就关闭了Statement或者Connection?比如不小心把stmt.close()写在了ResultSet遍历的前面,那结果集肯定用不了。
先从手动验证SQL开始排查,这是最快定位问题的方法!
内容的提问来源于stack exchange,提问作者1m9K

