离线 RowSet 是断开数据库连接后仍可操作数据的 CachedRowSet 等实现类,它缓存数据到内存,支持增删改查、游标滚动和事件监听;通过 execute() 自动完成查询与断连,acceptChanges() 同步变更回数据库。

Java 中 JDBC 通过 RowSet 实现离线处理结果集,核心在于使用实现了 javax.sql.RowSet 接口的离线实现类(如 CachedRowSet),它能在关闭数据库连接后仍保留并操作数据。
什么是离线 RowSet?
RowSet 是 ResultSet 的增强封装,分为两类:
-
Connected RowSet(如
JdbcRowSet):始终持有活跃数据库连接,不离线; -
Disconnected RowSet(如
CachedRowSet、WebRowSet):查询后自动断开连接,数据缓存在内存中,支持增删改查、游标滚动、事件监听等,真正实现“离线”。
常用的是 com.sun.rowset.CachedRowSetImpl(JDK 自带)或 Jakarta EE 中的 javax.sql.rowset.CachedRowSet(需引入 javax.sql.rowset 依赖)。
如何创建并填充 CachedRowSet?
步骤简洁:获取连接 → 执行查询 → 将 ResultSet 拷贝进 CachedRowSet → 关闭连接 → 离线操作。
示例代码:
CachedRowSet crs = new CachedRowSetImpl();
crs.setUrl("jdbc:mysql://localhost:3306/test");
crs.setUsername("user");
crs.setPassword("pass");
crs.setCommand("SELECT id, name FROM users WHERE age > ?");
crs.setInt(1, 18);
crs.execute(); // 自动连接、执行、拷贝、断开
// 此时 Connection 已关闭,crs 仍可使用
while (crs.next()) {
System.out.println(crs.getInt("id") + ": " + crs.getString("name"));
}
注意:execute() 内部完成连接、查询、数据填充和连接释放,无需手动管理 ResultSet 或 Connection。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
离线状态下怎么修改并同步回数据库?
CachedRowSet 支持在断网/断连状态下编辑数据,之后调用 acceptChanges() 重新建立连接并批量写回:
- 用
moveToInsertRow()+updateXXX()+insertRow()添加记录; - 用
updateXXX()+updateRow()修改当前行; - 用
deleteRow()删除当前行; - 调用
acceptChanges(Connection con)提交变更(需传入新连接)。
例如:
crs.last(); // 移到最后一条
crs.updateString("name", "Alice New");
crs.updateRow();
crs.moveToInsertRow();
crs.updateInt("id", 999);
crs.updateString("name", "New User");
crs.insertRow();
crs.acceptChanges(getNewConnection()); // 触发 INSERT/UPDATE/DELETE SQL
失败时抛出 SyncProviderException,可检查 getSyncResolver() 获取冲突详情(如乐观锁校验失败)。
注意事项与常见问题
重要提醒:
-
CachedRowSetImpl不是线程安全的,多线程访问需自行同步; - 数据全部加载到内存,大数据量慎用,避免 OOM;
- 默认不支持 BLOB/CLOB 流式处理,大字段建议用
SerialBlob显式转换; - JDK 9+ 中
com.sun.rowset属于内部 API,推荐迁移到 Jakarta EE 的javax.sql.rowset(如org.apache.commons.dbutils或rowset独立模块); - 离线期间无法感知底层数据变化,适合读多写少、短时离线场景(如 Web 表单编辑、报表预览)。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










