在《Java核心技术》上说,可滚动的行集虽然功能强大,但是一个重要缺陷是:在与用户交互过程中,必须始终与数据库保持连接,从而耗费数据库资源。而行集(RowSet)无需始终保持与数据库的连接。
但是又提到一个问题,如果在填充了行集之后,如果此时数据库中的数据发生了变化的话,容易造成数据库数据的不一致性。因此参考实现会首先检查行集中的原始值是否与数据库中的当前值一致,如果不一致,就抛出SyncProviderException异常。那么用RowSet如果每次都是去检查数据是否一致的话,岂不更浪费数据库的资源吗?ResultSet只是保持连接,而RowSet每次都去查询一次是否数据一致,岂不更费时?

解决方案 »

  1.   

    RowSet是JDBC 2.0开始提供的一个扩展包的接口,该接口可以允许我们作很多ResultSet不可做的事情。RowSet一共有3种具体的行集,它们是CachedRowSet、JdbcRowSet和WebRowSet。任何类型的rowset都实现了RowSet接口,RowSet接口扩展了ResultSet接口。这样RowSet对象就有了ResultSet对象所有的功能,能够通过getXXX方法得到数据库中的某列值,通过updateXXX方法可以修改某列值,可以移动光标,将当前行变为另一行。作为一个JavaBean组件,RowSet对象可以增加或者删除一个listener(监听者),可以get或者set其属性值。这些属性中,有一个是字符串,表示一个对数据库Query请求。RowSet接口定义了设定参数的方法,也提供了执行这个请求的方法。这意味着RowSet对象能够执行查询请求,可以根据它产生的结果集进行计算。同样,RowSet也可以根据任何表格数据源进行计算,所以,它不局限于关系数据库。从数据源得到数据之后,RowSet对象可以和数据源断开连接,rowset也可以被序列化。这样,RowSet就可以通过网络传递给瘦客户端。RowSet可以被重新连接到数据源,这样,做的修改就可以存回到数据源中去。如果产生了一个listener,当RowSet的当前行移动,或者数据被修改的时候,监听者就会收到通知。例如,图形用户界面组件可以注册成为监听者,当RowSet更改的时候,图形用户界面接到通知,就可以修改界面,来符合它所表示的RowSet。根据不同的需要,RowSet接口可以通过多种方法来实现。Java software已经写了一个CachedRowSet实现,从http://developer.java.sun.com/developer/earlyAccess/crs/index.html中可以得到这个实现。与CachedRowSet类不一样的是,JDBC RowSet类总是保持一个和数据源的连接。其实,它是在ResultSet的外层进行了一次包装,基于JDBC技术的驱动看起来像是一个简单的JavaBean组件一样。在JDBC 3.0 API中的有一个新特性就是可保持的结果集的支持。下面对其进行简单介绍。在上面一节,介绍了结果集的可滚动性和可更新性,但是从ResultSet接口的JDK文档中还可以看到这样两个特性参数:● CLOSE_CURSORS_AT_COMMIT:这个常量表示当调用Connection.commit方法的时候ResultSet对象自动关闭。● HOLD_CURSORS_OVER_COMMIT:这个常量表示当调用Connetion.commit方法的时候,ResultSet对象不会被关闭。这是3.0 API中提供的新特性,当使用HOLD_CURSORS_OVER_COMMIT参数的时候,驱动程序在修改结果被提交时可以不关闭ResultSet对象,这样在提交之后还可以对结果集进行一些需要的操作。默认情况下,创建Statement对象采用CLOSE_CURSORS_AT_COMMIT,这是为了保持和JDBC 1.0以及2.0兼容。但是对于可保持结果集的使用,需要驱动程序的支持,所以在使用这个特性的时候,查阅相应的文档以确定是否被支持是很必要的。读者可以从http://industry.java.sun.com/products/jdbc/drivers 网站上访问到当前驱动程序的列表。此外在JDBC 3.0中提供了一种很重要的改进结果集,那便是多重结果集。JDBC 2.0规范的一个局限是,在任意时刻,返回多重结果的语句只能打开一个ResultSet。作为JDBC 3.0规范中改变的一个部分,Statement接口支持多重打开的ResultSets将允许。然而,重要的是 execute() 方法仍然会关闭任何以前execute() 调用中打开的ResultSet。所以,要支持多重打开的结果,Statement接口就要加上一个重载的getMoreResults()方法。新的方法会做一个整数标记,在getResultSet()方法被调用时指定前一次打开的 ResultSet的行为。接口将按如下所示定义标记:● CLOSE_ALL_RESULTS:当调用getMoreResults()时,所有以前打开的ResultSet对象都将被关闭。● CLOSE_CURRENT_RESULT:当调用getMoreResults()时,当前的ResultSet对象将被关闭。● KEEP_CURRENT_RESULT:当调用getMoreResults()时,当前的ResultSet对象将不会被关闭。 
      

  2.   

    重要的:RowSet接口扩展了ResultSet接口。这样RowSet对象就有了ResultSet对象所有的功能