Java RowSet 使用完全剖析
RowSet 简介
wset自JDK 1.4 引入,从JDK 5.0 开始提供了参考实现。它主要包括CachedRowSet,WebRowSet,FilteredRowSet,JoinRowSet 和JdbcRowSet。除了JdbcRowSet 依然保持着与数据源的连接之外,其余四个都是Disconnected RowSet。
相比较java.sql.ResultSet而言,RowSet 的离线操作能够有效的利用计算机越来越充足的内存,减轻数据库服务器的负担,由于数据操作都是在内存中进行然后批量提交到数据源,灵活性和性能都有了很大的提高。RowSet 默认是一个可滚动,可更新,可序列化的结果集,而且它作为JavaBeans,可以方便地在网络间传输,用于两端的数据同步。
回页首类继承结构
RowSet 继承自ResultSet,其他五个RowSet 接口均继承自RowSet。下图是它们的继承关系。
图  1. 继承结构图
表  3. 表ORDERS
ID USER_ID PRODUCT
1    1 Book
2    1 Computer
3    2 Phone
回页首使用CachedRowSet
填充CachedRowSet 的两种方式
CachedRowSet 提供了两个用来获取数据的方法,一个是execute(),另一个是populate(ResultSet)。
使用execute()填充CachedRowSet 时,需要设置数据库连接参数和查询命令command,如下示例代码:
cachedRS 根据设置的url、username、password 三个参数去创建一个数据库连接,然后执行查询命令command,用结果集填充cachedRS,最后关闭数据库连接。execute()还可以直接接受一个已经打开的数据库连接,假设conn 为一个已经打开的数据库连接,下段示例代码与上段代码结果一致:
填充CachedRowSet 的第二个方法是使用populate(ResultSet)。
CachedRowSet 本身也是继承于ResultSet,因此,也可以用一个有数据的CachedRowSet 来填充另一个CachedRowSet。
更新、删除、插入数据
更新数据。先把游标(cursor)移到要更新的行,根据每列的类型调用对应的updateXXX(index, updateValue),再调用updateRow()方法。此时,只是在内存中更新了该行,同步到数据库需要调用方法acceptChanges()或acceptChanges(Connection)。如果CachedRowSet 中保存着原数据库连接信息,则可以调
用acceptChanges();否则,则应该传入可用的数据库连接或重新设置数据库连接参数。下段示例代码更新第一行的第二列。
删除数据。把游标移到要删除的行,调用deleteRow(),再同步回数据库即可。
在删除数据时,需要注意布尔值showDeleted 这个属性的使用。CachedRowSet 提供了getShowDeleted()和setShowDeleted(boolean value)两个方法来读取和设置这个属性。showDeleted 是用来判断被标记为删除且尚未同步到数据库的行在CachedRowSet 中是否可见。true 为可见,false 为不可见。默认值为false。
插入数据。插入操作稍微比更新和删除复杂。先看下段示例代码。
新插入的行位于当前游标的下一行。本例中,先把游标移到最后一行,那么在新插入数据后,新插入的行就是最后一行了。在新插入行时,一定要先调用方法moveToInsertRow(),然后调用updateXXX()设置各列值,再调用insertRow(),最后再把游标移到当前行。注意一定要遵循这个步骤,否则将抛出异常。
冲突处理
当我们使用CachedRowSet 更新数据库时,有可能因为内存中的数据过期而产生冲突。此时更新数据库的方
法acceptChanges()会抛出SyncProviderException,由此我们可以捕获产生冲突的原因并手动进行解
resultset 遍历决。
我们首先填充cachedRS,然后在数据库中直接修改ID 为1 的行,将NAME 字段设为"Terry",同时用cachedRS 修改ID 为  1 的行的REMARK 字段,最后使用acceptChanges 跟数据库进行同步。此时cachedRS 中记录的原始值与数据库中的值不一致,从而产
生冲突,抛出SyncProviderException,数据也会更新失败。接下来我们通过SyncProviderException 得到SyncResolver 实例并遍历了产生的所有冲突。
SyncResolver 继承了RowSet 接口,我们可以像使用一般RowSet 一样操作它。SyncResolver 的实例拥有与正在同步的RowSet 相同的行数和列数。使用nextConflict()和previousConflict()可以遍历所有产生的冲突,getStatus()可以获得冲突的类型。在SyncResolve 中定义了四种类型,分别是:DELETE_ROW_CONFLICT,INSERT_ROW_CONFLICT,
NO_ROW_CONFLICT,UPDATE_ROW_CONFLICT。上例中产生的是UPDATE_ROW_CONFLICT。
注:目前Sun JDK 对SyncResolver 的支持非常有限,只实现了SyncResolver 接口中定义的方法,调用从RowSet 接口继承的方法都会抛出UnsupportedOperationException异常;getConflictValue()返回都是null。
事件监听
一个需要实现RowSetListener 接口。RowSetListener 支持三种事件监听:cursor moved、row changed 和rowSet changed。假定Listener 实现了RowSetListener 接口,看示例代码。
updateOnRowSet()所做的操作就是将游标移到第一行,更新,再同步回数据库。在这个方法中,依次触发了Listener 的三个事件。下表列出了CachedRowSet 中会触发的所有方法。
表  4. CachedRowSet 中会触发的方法
cursor moved row changed rowSet changed absolute() √
relative() √
next() √
previous() √
first() √
last() √
beforeFirst() √
afterLast() √
updateRow() √
deleteRow() √
insertRow() √
undoDelete() √
undoUpdate() √

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。