You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSH隧道连接MySQL后,JDBC代码执行rs.last()抛出ResultSet类型不允许操作的SQLException问题

SSH隧道连接MySQL后,JDBC代码执行rs.last()抛出ResultSet类型不允许操作的SQLException问题

嘿,这个问题其实和SSH隧道本身没啥关系,核心是你创建的ResultSet默认类型不支持游标来回移动操作!

先给你拆解下报错原因:当你调用rs.last()时,JDBC抛出Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY,这是因为默认情况下,通过connection.prepareStatement(sql)创建的PreparedStatement,生成的ResultSet是只能单向向前遍历的类型(TYPE_FORWARD_ONLY),这种类型不允许调用last()、beforeFirst()这类需要移动游标到非当前位置之后的操作。之前你的代码能正常运行,大概率是之前的环境里JDBC驱动或连接配置无意中帮你设置了可滚动的ResultSet,但换了SSH隧道连接后(其实本质是连接配置没改,只是现在默认行为生效了),就触发了这个限制。

解决方法很简单:创建PreparedStatement时显式指定可滚动的ResultSet类型

修改你创建PreparedStatement的代码,加上ResultSet类型和并发模式参数:

// 替换原来的ps = connection.prepareStatement(mark_complete);
ps = connection.prepareStatement(mark_complete, 
                                ResultSet.TYPE_SCROLL_INSENSITIVE, 
                                ResultSet.CONCUR_READ_ONLY);
  • ResultSet.TYPE_SCROLL_INSENSITIVE:允许游标自由滚动(前后移动都可以),且对数据库的修改不会反映到ResultSet中(适合你的只读场景)
  • ResultSet.CONCUR_READ_ONLY:设置ResultSet为只读模式,符合你只是读取数据写入Excel的需求

顺便提下你代码里的两个小问题

  1. 代码里的connection.createStatement();这行完全没用,你创建了一个Statement对象但没赋值给任何变量,也没使用,属于无效代码,建议删掉,避免浪费资源。
  2. 你的while循环逻辑有点问题:在for循环里又调用了一次rs.next(),结合外层的rs.next()和while (r < size),可能会导致游标移动异常,甚至跳过部分数据。建议梳理下遍历逻辑,比如改成:
int index = 0;
while (rs.next()) {
    index++;
    Row row = sheet.createRow((short) index);
    String value1 = rs.getString(1);
    row.createCell(0).setCellValue(value1);
    String value2 = StringUtils.left(rs.getString(2), 16);
    row.createCell(1).setCellValue(value2);
}

这样直接用rs.next()来遍历,既简洁又不容易出错,还能省去调用rs.last()获取行数的步骤(如果不是必须要提前知道行数的话)。

备注:内容来源于stack exchange,提问作者David S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 14:47:30