现在的J2SE 5.0中,可以把JDBC API分为三种类别,除了上面的两类,还有RowSet接口的5种标准实现。这些实现提供了一组接口,以扩展基本的RowSet接口,通过在这些接口上建立application,可以确保在事件处理、游标控制以及其他操作方面的实现遵循JDBC API。
RowSet接口提供了一组基本方法,这些方法对于所有行集都是通用的。因为所有的RowSet对象都是JavaBean组件,因此,RowSet接口具有添加和删除event listener的方法,也有get/set RowSet对象所有属性的方法。RowSet对象的大多数属性都支持建立连接或者执行命令。为了执行查询、更新等SQL语句,并生成能够从中获取数据的结果集,行集会使用到数据源的连接。
若一个组件希望得到在RowSet对象上发生的事件的通知,它就应该实现RowSetListener接口,并向RowSet对象进行注册。这就是listener,一个GUI组件。这样每当行集产生事件时,listener每次都会得到事件的通知,这样就能够保持它的游标位置和数据与行集的内容一致。
RowSetInternal、RowSetReader、和RowSetWriter接口支持行集的reader/weiter工具。reader是一个实现RowSetReader接口的类的实例,用来读取数据并数据插入到行集中。writer是一个实现RowSetWriter接口的类的实例,用来将修改后的数据写回到数据源。reader和writer就像是listener一样,都向行集进行动态注册。
调用reader或者writer的RowSet对象必须是实现RowSetInternal接口的类的实例。这个接口为reader或者writer提供了附加的方法,用来操作行集的内部状态。例如行集可以跟踪它的初始值,RowSetInternal方法允许writer检测数据源中的相应数据是否已经被其他用户修改。另外,能够使用RowSetInternal方法来获取为行集的命令字符串设置的输入参数,也能够获取传递给行集的连接。最后,RowSetInternal方法允许reader设置新的RowSetMetaData对象,这个对象用来为行集描述reder将要插入到该行集中的数据行。
行集可以是connected的,也可以是disconnected的,一个连接的RowSet对象,在使用的整个过程中保持到数据源的连接,而一个未连接的行集,只有从数据源读取数据或者将数据写回数据源时才会连接到它的数据源。若行集是未连接的,它就不需要JDBC驱动或者JDBC API的完整实现。这使得它非常小巧,因此也成为发送一组数据到一个thin client的理想的容器。这个客户端可以选择更新数据,并将行集发送回应用服务器。在服务器端,未连接的RowSet对象使用它的reader来建立到数据源的连接,并把数据写回数据源。这一操作的具体实现依赖于reader的实现方式。通常reader将建立连接与读/写数据的操作委托给JDBC驱动。
行集的事件模型
行集事件模型使得Java对象或者组件能够收到RowSet对象产生的事件的通知。通知机制的建立包括被通知的组件,也包括RowSet对象自身。首先,每一个希望得到事件通知的组件都必须实现RowSetListener接口。然后,RowSet对象必须注册每一个组件,这通过在RowSet对象的事件通知组件列表中添加这些组件来完成。在这种情况下,这样的组件是一个listener,它是一个实现RowSetListener方法的类的实例,并已经向RowSet对象进行过注册。
在RowSet对象中可能发生三种事件:游标移动、数据行发生变化(ins、del、upd)或者该对象的整个内容发生变化。RowSetListener接口的cursorMoved、rowChanged和rowSetChanged方法分别对应与这些事件。当事件发生时,行集将创建一个RowSetEvent对象,使用这个对象将该行集标识为事件源。在每一个listener上调用适当的RowSetListender方法,并向此方法传递一个RowSetEvent对象作为输入参数,就将事件通知给行集所有的listener。
RowSet属性
RowSet接口提供了一组JavaBeans属性,可以配置RowSet实例以连接到数据源并获取数据行集合。有些属性可能并不需要,这取决于特定实现。如用URL或者数据源名来建立连接,但只要设置了其中一个属性,另一个属性就是可选的。如果设置了两个属性,就会使用最近设置的那个属性。若行集的数据是从不支持名命令的非SQL数据源中如电子表格中获取的,那么就不需要设置命令属性。
几个接口的讲解
WebRowSetWebRowSet接口扩展了CacheRowSet接口。相比CacheRowSet接口,增加了读写XML格式行集的能力。WebRowSetImpl对象使用WebRowSetXmlReader对象来读取XML格式的行集,使用WebRowSetXmlWriter对象向XML格式的行集中写入数据。XML版本包含WebRowSetSetImpl对象的元数据,同时也包含它自己的数据。 WebRowSetImpl对象和CachedRowSetImpl相似点是二者都将瘦客户端连接到应用服务器。所以它们都适合为瘦客户提供数据;不同的地方是二者使用的协议。前者使用http/xml协议与中间层进行通信,而后者使用RMI/IIOP。
JoinRowSet
JoinRowSet对象使得程序员能够从两个不同的RowSet对象合并数据。当相关联(p/f keys相关或者其他列唯一对应)的数据存储在不同的数据源中时,这种合并数据的功能很有用。任何RowSet实现都可以参与合并,但通常情况下,连接的双方是两个CachedRowSetImpl对象。将相关数据合并到一个JoinRowSetImpl对象中,应用程序就能够处理任何其他类型的RowSet对象一样来处理这些数据。
假设有两个表:employees表和bonus_plan表,两表的第一个数据列都是ID,这个数据列是主键,现要将两表的信息进行匹配合并: JoinRowSetImpl jrs=new JoinRowSetImpl(); ResultSet rs1 = stmt.executeQuery(“select * from employees”); CachedRowSetImpl empl=new CachedRowSetImpl(); empl.populate(rs1); empl.setMatchColumn(1); jrs.addRowSet(empl); ResultSet rs2=stmt.executeQuery(“select * from bonum_plan”); CachedRowSetImpl bonums= new CachedRowSetImpl(); bonus.populate(rs2); bonus.setMatchColumn(1); jrs.addRowSet(bonus);//已合并