RowSet 新特性简介

来源:互联网 发布:手机人物模型软件 编辑:程序博客网 时间:2024/06/15 16:22

RowSet 新特性简介

Java 5在Java Database Connectivity (JDBC)方面加强了支持,其中加入了新的包javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi。从RowSet接口继承规定了五个新的接口:

1. CachedRowSet: CachedRowset可以不用与数据源建立长期的连接,只有当从数据库读取数据或是往数据库写入数据的时候才会与数据库建立连接,它提供了一种轻量级的访问数据库的方式,其数据均存在内存中。

2. JdbcRowSet:对ResultSet的对象进行包装,使得可以将ResultSet对象做为一个JavaBeans ™ 组件。

3. FilteredRowSet:继承自CachedRowSet,可以根据设置条件得到数据的子集。

4. JoinRowSet:继承自CachedRowSet,可以将多个RowSet对象进行SQL Join语句的合并。

5. WebRowSet:继承自CachedRowSet,可以将WebRowSet对象输出成XML格式。

下面分别演示如何使用这五个新接口。

CachedRowSet

CachedRowSet可以通过调用populate(ResuletSet rs)来生成数据,一旦获得数据,CachedRowSet就可以断开与数据库的连接,直到往数据库写入数据的时候才需建立连接。

可以使用自己扩展的或是使用Reference Implement的实现类进行访问数据库。下面的代码演示了如何根据ResultSet建立一个CachedRowSet对象,在中断与数据库连接的情况下,读取数据,并做更新,最后再获取数据库连接,将更新落实到数据库中。

public static void testCachedRowSet(){Connection conn = null;try {// 获得数据库连接    conn= DriverManager.getConnection(DB2URL, DB2USER, DB2PASSWORD);    Statement stmt = conn.createStatement();    // 查询数据库,获得表数据    ResultSet rs = stmt.executeQuery("select * from student");//$NON-NLS-1$    // 根据ResultSet对象生成CachedRowSet类型的对象    CachedRowSetImpl crs = new CachedRowSetImpl();    crs.populate(rs);    // 关闭ResultSetrs.close();    // 关闭数据库的连接    conn.close();    // 在中断与数据库连接的情况下,对CachedRowSet进行操作    operateOnRowSet(crs);    // 重新获取与数据库的连接    conn= DriverManager.getConnection(DB2URL, DB2USER, DB2PASSWORD);    // 将CachedRowSet的内容更新到数据库    crs.acceptChanges(conn);    // 关闭CachedRowSet    crs.close();    // 关闭数据库连接    conn.close();} catch (InstantiationException e) {    System.out.println("Andrew: InstantiationException!");//$NON-NLS-1$} catch (IllegalAccessException e) {    System.out.println("Andrew: IllegalAccessException!");//$NON-NLS-1$} catch (ClassNotFoundException e) {    System.out.println("Andrew: ClassNotFoundException!");//$NON-NLS-1$}catch (SQLException e) {  System.out.println("Andrew: SQLException!");//$NON-NLS-1$e.printStackTrace();}}

其中operateOnRowSet方法遍历读取RowSet中的元素,并将id值加1。RowSet允许注册监听器,可以在光标移动,RowSet发生改变时触发。其具体代码如下:

public static void operateOnRowSet(RowSet rs){// 为RowSet注册监听器MyRowsetListener myListener = new MyRowsetListener();    rs.addRowSetListener(myListener);    // 操作RowSet数据try{// 遍历读取数据while (rs.next()) {String id = rs.getString("ID");//$NON-NLS-1$        String name = rs.getString("NAME");//$NON-NLS-1$        System.out.println("ID="+id+",NAME="+name);//$NON-NLS-1$        //在id最末位连接"1"        rs.updateString(1, id+"1");    }}catch (SQLException e) {    System.out.println("Andrew: SQLException!");//$NON-NLS-1$e.printStackTrace();}}class MyRowsetListener implements RowSetListener{// 光标发生移动public void cursorMoved(RowSetEvent event) {System.out.println("cursor moved");}// row发生改变public void rowChanged(RowSetEvent event) {System.out.println("row changed");}// RowSet发生改变public void rowSetChanged(RowSetEvent event) {System.out.println("row set changed");}}public static void main(String[] args) {try {Class.forName(DB2DRIVER).newInstance();} catch (InstantiationException e) {System.out.println("Andrew: InstantiationException!");//$NON-NLS-1$} catch (IllegalAccessException e) {System.out.println("Andrew: IllegalAccessException!");//$NON-NLS-1$} catch (ClassNotFoundException e) {System.out.println("Andrew: ClassNotFoundException!");//$NON-NLS-1$}testCachedRowSet();}

上面的程序的运行结果如下:

cursor movedID=001,NAME=zhoucursor movedID=002,NAME=zhangcursor movedcursor movedcursor movedcursor movedcursor movedcursor movedrow set changed

并且数据库中的id更新为0011,0021。

 

 

JdbcRowSet

JdbcRowSet功能与ResultSet类似,与CachedRowSet不同,JdbcRowSet在操作时保持与数据库的连接。可以将与数据库连接的URL,用户名,密码以及执行的SQL语句通过setXXX形式绑定。另外,JdbcRowSet返回的结果默认是可以上下滚动和可更新的,当然这需要数据库厂商提供的JDBC Driver支持。下面的代码演示了如何通过set方法设定数据库连接参数,以及如何操作JdbcRowSet对象。

public static void testJdbcRowSet() {JdbcRowSetImpl jrs = new JdbcRowSetImpl();try {// 设置连接数据库的URLjrs.setUrl(DB2URL);// 设置连接数据库的用户名jrs.setUsername(DB2USER);// 设置连接数据库的密码jrs.setPassword(DB2PASSWORD);// 设置执行数据库的SQL语句jrs.setCommand("select * from student");// 执行操作jrs.execute();// 对获得的JdbcRowSet进行操作operateOnRowSet(jrs);// 关闭JdbcRowsetjrs.close();} catch (SQLException e) {System.out.println("Andrew: SQLException!");//$NON-NLS-1$e.printStackTrace();}}public static void operateOnRowSet(RowSet rs) {// 为RowSet注册监听器MyRowsetListener myListener = new MyRowsetListener();rs.addRowSetListener(myListener);// 操作RowSet数据try {// 遍历读取数据while (rs.next()) {String id = rs.getString("ID");//$NON-NLS-1$String name = rs.getString("NAME");//$NON-NLS-1$System.out.println("ID=" + id + ",NAME=" + name);//$NON-NLS-1$}} catch (SQLException e) {System.out.println("Andrew: SQLException!");//$NON-NLS-1$e.printStackTrace();}}

其运行结果如下:

cursor movedID=0011,NAME=zhoucursor movedID=0021,NAME=zhangcursor moved

 

 

FilteredRowSet

FilteredRowSet接口中规定了可以设定过滤器,其过滤接口为Predicate接口,必须实现Predicate接口中的evaluate方法。具体的代码如下:

public static void testFilteredRowSet() {try {// 获得数据库连接Connection conn = DriverManager.getConnection(DB2URL, DB2USER,DB2PASSWORD);Statement stmt = conn.createStatement();// 查询数据库,获得表数据ResultSet rs = stmt.executeQuery("select * from student");//$NON-NLS-1$FilteredRowSet frs = new FilteredRowSetImpl();frs.populate(rs);// 设置过滤器MyDBFilter filter = new MyDBFilter(11, 100);frs.setFilter(filter);operateOnRowSet(frs);// 关闭FilteredRowSetfrs.close();// 关闭与数据库的连接conn.close();} catch (SQLException e) {System.out.println("Andrew: SQLException!");//$NON-NLS-1$e.printStackTrace();}}public static void operateOnRowSet(RowSet rs) {// 为RowSet注册监听器System.out.println("operateOnRowSet!");//$NON-NLS-1$MyRowsetListener myListener = new MyRowsetListener();rs.addRowSetListener(myListener);// 操作RowSet数据try {// 遍历读取数据while (rs.next()) {String id = rs.getString("ID");//$NON-NLS-1$String name = rs.getString("NAME");//$NON-NLS-1$System.out.println("ID=" + id + ",NAME=" + name);//$NON-NLS-1$}} catch (SQLException e) {System.out.println("Andrew: SQLException!");//$NON-NLS-1$e.printStackTrace();}}public static void main(String[] args) {try {Class.forName(DB2DRIVER).newInstance();} catch (InstantiationException e) {System.out.println("Andrew: InstantiationException!");//$NON-NLS-1$} catch (IllegalAccessException e) {System.out.println("Andrew: IllegalAccessException!");//$NON-NLS-1$} catch (ClassNotFoundException e) {System.out.println("Andrew: ClassNotFoundException!");//$NON-NLS-1$}testFilteredRowSet();}

其中MyDBFilter实现了Predicate接口,其实现代码如下:

class MyDBFilter implements Predicate {private int low;private int high;public MyDBFilter(int low, int high) {this.low = low;this.high = high;}public boolean evaluate(RowSet rs) {CachedRowSet crs=(CachedRowSet)rs;//如果id在low和high之间返回真try {String id = (String) crs.getString("id");int idValue = Integer.parseInt(id);if (low < idValue && idValue < high) {return true;}} catch (SQLException e) {}return false;}public boolean evaluate(Object arg0, int arg1) throws SQLException {return false;}public boolean evaluate(Object arg0, String arg1) throws SQLException {return false;}}

其运行结果如下:

cursor movedID=0021,NAME=zhangcursor moved

 

JoinRowSet

JoinRowSet可以将多个RowSet对象进行join合并,Join的列可以通过每个RowSet通过调用setMatchColumn方法来设置。setMatchColumn方式是Joinable接口定义的方法,五种类型的RowSet规定都需要实现该接口。下面的代码演示将student表和intern表中id相同的数据进行join操作。JoinRowSet不需要保持与数据库的连接。

public static void testJoinRowSet(){Connection conn = null;try {JoinRowSet jrs = new JoinRowSetImpl();// 获得数据库连接conn = DriverManager.getConnection(DB2URL, DB2USER, DB2PASSWORD);Statement stmt = conn.createStatement();// 查询数据库,获得表数据ResultSet rs1 = stmt.executeQuery("select id,name from student");//$NON-NLS-1$// 根据ResultSet对象生成CachedRowSet类型的对象CachedRowSetImpl crs1 = new CachedRowSetImpl();crs1.populate(rs1);crs1.setMatchColumn(1);// 关闭ResultSetjrs.addRowSet(crs1);rs1.close();// 查询数据库,获得表数据ResultSet rs2 = stmt.executeQuery("select id,company from intern");//$NON-NLS-1$// 根据ResultSet对象生成CachedRowSet类型的对象CachedRowSetImpl crs2 = new CachedRowSetImpl();crs2.populate(rs2);crs2.setMatchColumn(1);// 关闭ResultSetrs2.close();// 将Result2放入JoinRowSet中进行Join操作jrs.addRowSet(crs2);// 关闭数据库连接conn.close();while (jrs.next()) {String id = jrs.getString(1);String name = jrs.getString(2);String company = jrs.getString(3);//$NON-NLS-1$System.out.println("ID=" + id + ",NAME=" + name+",COMPNAY="+company);}} catch (SQLException e) {System.out.println("Andrew: SQLException!");//$NON-NLS-1$e.printStackTrace();}}

其输出结果为

ID=001111,NAME=zhou,COMPNAY=companyA

 

WebRowSet

WebRowSet继承自CachedRowSet,支持XML格式的查询,更新等操作,下面的代码将WebRowSet对象输出成XML格式到文件。

public static void testWebRowSet(){try {// 获得数据库连接Connection conn = DriverManager.getConnection(DB2URL, DB2USER,DB2PASSWORD);Statement stmt = conn.createStatement();// 查询数据库,获得表数据ResultSet rs = stmt.executeQuery("select * from student");//$NON-NLS-1$WebRowSetImpl wrs = new WebRowSetImpl();wrs.populate(rs);FileOutputStream out = new FileOutputStream("data.xml");wrs.writeXml(out);wrs.close();// 关闭与数据库的连接conn.close();} catch (SQLException e) {System.out.println("Andrew: SQLException!");//$NON-NLS-1$e.printStackTrace();} catch(IOException e){System.out.println("Andrew: IOException!");//$NON-NLS-1$e.printStackTrace();}}

其运行结果data.xml大致如下:

XML文件属性格式 ……    2          1      false      true      false      0      false      true      10      ID      ID      ZHOUDP        10      0      STUDENT      TEST      12      VARCHAR              2      false      true      false      1      false      true      50      NAME      NAME      ZHOUDP        50      0      STUDENT      TEST      12      VARCHAR                  0011      zhou              0021      zhang
0 0