CachedRowSet是JDBC中实现离线操作的核心接口,支持断开连接后的增删改查及回写;通过populate()加载数据、updateRow()等修改缓存、acceptChanges()同步数据库,需主键标识行且注意内存与并发限制。

RowSet 是 JDBC 中专为离线操作设计的接口,它本质是可滚动、可更新、可序列化的 ResultSet 增强版,但不依赖活跃数据库连接。要真正实现“离线读取 + 修改 + 回写”,关键不是只用 RowSet 接口本身(它是规范),而是选用支持离线能力的具体实现类——最常用的是 javax.sql.rowset.CachedRowSet(JDBC 标准内置,无需额外依赖)。
1. 使用 CachedRowSet 实现离线读取
CachedRowSet 在执行查询后会把结果集数据全部缓存到内存中,并自动关闭底层 ResultSet 和 Connection,彻底断开数据库连接。
- 通过
RowSetProvider.newFactory().createCachedRowSet()获取实例(推荐,符合 JDBC 4.1+ 规范) - 设置数据库连接参数(url、user、password)和 SQL 查询语句(
setUrl()、setUsername()、setPassword()、setCommand()) - 调用
execute()执行查询——此时建立连接、获取数据、缓存、关闭连接一气呵成 - 之后即使网络断开或 Connection 关闭,仍可自由遍历、定位、获取字段值
2. 在离线状态下修改数据
CachedRowSet 默认支持插入、更新、删除操作,所有变更都只作用于本地缓存,不影响数据库。
- 调用
beforeFirst()或absolute(n)定位到目标行 - 用
updateXXX("列名", 新值)修改字段(如updateString("name", "张三")) - 调用
updateRow()提交当前行修改(仅更新缓存) - 新增行:调用
moveToInsertRow()→updateXXX()→insertRow() - 删除行:定位后调用
deleteRow()
3. 将离线修改同步回数据库(回写)
回写不是自动发生的,必须显式调用 acceptChanges(),它会重建连接,生成并执行对应 INSERT/UPDATE/DELETE 语句。
立即学习“Java免费学习笔记(深入)”;
-
acceptChanges()内部使用之前设置的连接参数重新建立 Connection - 自动识别哪些行被插入、更新、删除,并生成标准 SQL 执行(基于主键或唯一约束判断行身份)
- 若表无主键,需提前调用
setKeyColumns(new int[]{1})指定主键列索引(否则更新/删除可能失败) - 执行失败会抛出 SQLException,需捕获处理;成功后 RowSet 状态重置为“已同步”
4. 注意事项与常见问题
CachedRowSet 虽方便,但有隐含约束,忽略易导致异常或静默失败:
- 查询 SQL 必须能明确标识每一行(建议 SELECT 所有主键列,避免 SELECT * 且表无主键)
- 修改前确保已调用
setReadOnly(false)(部分实现默认只读) - 回写时若数据库结构变化(如列删改)、并发冲突(他人已改同一行),
acceptChanges()会报错 - 大数据量慎用——所有数据驻留 JVM 内存,可能引发 OOM
- 不支持 BLOB/CLOB 的离线流式操作,大对象需特殊处理


















