NetBeans17中出现ResultSet.TYPE_FORWARD_ONLY SQLException问题求助
解决java.sql.SQLException: Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY
问题根源
你调用rs.last()和rs.first()时触发异常,是因为默认通过Connection.createStatement()创建的Statement,生成的ResultSet是**仅向前滚动(TYPE_FORWARD_ONLY)**的,这类ResultSet只允许用next()单向移动游标,不支持前后跳转操作。旧版NetBeans搭配的MySQL驱动可能放宽了JDBC规范限制,而NetBeans17适配的新版驱动严格遵循规范,所以报错。
修复步骤
修改QueryProcessor构造方法里创建Statement的代码,显式指定可滚动的ResultSet类型:
public QueryProcessor() { try { DBConnection.setConnection(); con = DBConnection.getConnection(); // 替换原有createStatement调用,指定可滚动、只读的ResultSet stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); } catch (Exception e) {e.printStackTrace();} }
TYPE_SCROLL_INSENSITIVE表示ResultSet支持前后滚动,且对数据库的修改不敏感;CONCUR_READ_ONLY表示ResultSet是只读的,符合你代码仅做查询的场景。
额外优化点
- 避免成员变量资源冲突:你的
rs、stmt是类成员变量,多线程调用时会出现资源覆盖问题,建议改为方法内局部变量,并在finally块中关闭资源,防止泄漏:
public String[][] getAllRecord(String query) { String row[][] = null; ResultSet rs = null; Statement stmt = null; ResultSetMetaData metadata = null; try { stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); rs = stmt.executeQuery(query); if (rs.last()) { metadata = rs.getMetaData(); row = new String[rs.getRow()][metadata.getColumnCount()]; rs.first(); int r = 0; do { for (int col = 0; col < metadata.getColumnCount(); col++) { row[r][col] = rs.getString(col+1); } r++; } while(rs.next()); } } catch (Exception e) { e.printStackTrace(); } finally { // 按逆序关闭资源 try { if(rs != null) rs.close(); } catch(Exception ignore) {} try { if(stmt != null) stmt.close(); } catch(Exception ignore) {} } return row; }
- 修复索引越界问题:
getSpecificField方法中rs.getString(col)会导致索引越界,JDBC列索引从1开始,应改为rs.getString(col+1)。
内容的提问来源于stack exchange,提问作者Jake Vincent Seraspe
相关产品推荐
相关产品推荐

