ResultSet.TYPE_FORWARD_ONLY结果集操作异常解决方案咨询
解决java.sql.SQLException: Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY异常
这个异常的核心原因是:你使用的默认结果集(ResultSet)类型是TYPE_FORWARD_ONLY,它只能单向向前遍历,不支持last()、beforeFirst()这类任意移动游标的操作。下面给你两种可行的解决办法:
方法一:创建支持滚动的结果集
修改prepareStatement的调用方式,显式指定结果集类型为支持滚动的类型,同时设置并发模式为只读(因为你只需要统计行数,不需要修改数据):
Class.forName("com.mysql.cj.jdbc.Driver"); Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/onlineshop?autoReconnect=true&useSSL=false","root",DatabaseConnection.root); // 新增两个参数,指定结果集支持滚动且只读 PreparedStatement ps=con.prepareStatement("select * from custinfo", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet rs=ps.executeQuery(); // 统计行数的代码可以正常运行了 if(rs.last()) { x=rs.getRow(); rs.beforeFirst(); }
TYPE_SCROLL_INSENSITIVE表示结果集可以自由滚动,且对数据库的修改不会反映到结果集中(适合只读场景);CONCUR_READ_ONLY表示结果集是只读的,避免不必要的资源消耗。
方法二:直接用SQL统计行数(更推荐)
如果你的需求只是统计行数,没必要查询整个表的数据,直接执行count(*)查询会更高效,还能避免结果集滚动的问题:
Class.forName("com.mysql.cj.jdbc.Driver"); Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/onlineshop?autoReconnect=true&useSSL=false","root",DatabaseConnection.root); PreparedStatement ps=con.prepareStatement("select count(*) from custinfo"); ResultSet rs=ps.executeQuery(); if(rs.next()) { x=rs.getInt(1); // 直接获取统计的行数 }
这种方式只返回一个数值,不需要处理大结果集,性能更优,代码也更简洁。
内容的提问来源于stack exchange,提问作者Vaishali Davargave
相关产品推荐
相关产品推荐

