Java SQL异常:Closed Resultset: next问题求助(未关连接/结果集)
解决"Closed Resultset: next"异常的问题
嘿,我一眼就发现你代码里的问题了!这个异常完全是因为你错误地初始化了ResultSet,并且没有正确获取查询返回的结果集导致的,和你有没有关闭连接/ResultSet没关系。
问题出在哪?
你看这段代码:
public Integer findByName(String name) throws SQLException { Connection con = Database.getConnection(); try (Statement stmt = con.createStatement(); ResultSet rs = stmt.getResultSet()) { stmt.executeQuery("select id from artists where name='" + name + "'"); return rs.next() ? rs.getInt(1) : null; } }
- 你在try-with-resources里先调用了
stmt.getResultSet(),但这时候你还没执行任何查询语句,这个ResultSet根本就是未打开的(或者说已经处于关闭状态)。 - 之后你执行
stmt.executeQuery(),它会返回一个全新的、有效的ResultSet,但你完全没把这个结果集赋值给rs变量,后续操作的还是那个一开始就无效的ResultSet,调用rs.next()自然就会抛出"Closed Resultset: next"异常。
另外还要提醒你:用字符串拼接参数name='" + name + "'"会导致SQL注入漏洞,这是非常危险的做法,一定要改用PreparedStatement来处理参数。
修正后的代码
版本1:修正原Statement的写法
public Integer findByName(String name) throws SQLException { try (Connection con = Database.getConnection(); Statement stmt = con.createStatement(); // 直接把executeQuery的返回值作为ResultSet初始化 ResultSet rs = stmt.executeQuery("select id from artists where name='" + name + "'")) { return rs.next() ? rs.getInt(1) : null; } }
版本2:更安全的PreparedStatement写法(强烈推荐)
public Integer findByName(String name) throws SQLException { // 使用预编译SQL,避免SQL注入 String sql = "select id from artists where name = ?"; try (Connection con = Database.getConnection(); PreparedStatement pstmt = con.prepareStatement(sql);) { // 设置参数,索引从1开始 pstmt.setString(1, name); try (ResultSet rs = pstmt.executeQuery()) { return rs.next() ? rs.getInt(1) : null; } } }
关键修正点
- 把
executeQuery()的返回值直接作为ResultSet的初始化值,放在try-with-resources中,确保结果集是有效的,并且会被自动关闭。 - 改用
PreparedStatement处理参数,彻底避免SQL注入风险,同时让代码更健壮。
内容的提问来源于stack exchange,提问作者v_manoliu
相关产品推荐
相关产品推荐

