跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

使用 Java 5 RowSet 新特性访问 IBM DB2 数据库

张黄瞩,zhanghuangzhu@gmail.com,熟悉 WBI Server Foundation, WPS 6.0,对Java,C/C++编程有浓厚的兴趣。

简介: Java 5 在 Java Database Connectivity (JDBC) 方面加强了支持,其中加入了新的包 javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi。本文将通过实例来演示这些新的特性。

发布日期: 2006 年 4 月 10 日
级别: 初级
访问情况 : 1444 次浏览
评论: 


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 格式。

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


实验环境

IBM DB2 Universal 8.1
数据库名:DemoDB
数据库用户名:db2admin
数据库密码:password


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); 
	    // 关闭 ResultSet 
		 rs.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 moved 
 ID=001,NAME=zhou 
 cursor moved 
 ID=002,NAME=zhang 
 cursor moved 
 cursor moved 
 cursor moved 
 cursor moved 
 cursor moved 
 cursor moved 
 row 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 { 
		 // 设置连接数据库的 URL 
		 jrs.setUrl(DB2URL); 
		 // 设置连接数据库的用户名
		 jrs.setUsername(DB2USER); 
		 // 设置连接数据库的密码
		 jrs.setPassword(DB2PASSWORD); 
		 // 设置执行数据库的 SQL 语句
		 jrs.setCommand("select * from student"); 
		 // 执行操作
		 jrs.execute(); 
		 // 对获得的 JdbcRowSet 进行操作
		 operateOnRowSet(jrs); 
		 // 关闭 JdbcRowset 
		 jrs.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 moved 
 ID=0011,NAME=zhou 
 cursor moved 
 ID=0021,NAME=zhang 
 cursor 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); 
		 // 关闭 FilteredRowSet 
		 frs.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 moved 
 ID=0021,NAME=zhang 
 cursor 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); 
         // 关闭 ResultSet 
         jrs.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); 
         // 关闭 ResultSet 
         rs2.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 version="1.0"?> 
 XML 文件属性格式 
……
 <metadata> 
    <column-count>2</column-count> 
    <column-definition> 
      <column-index>1</column-index> 
      <auto-increment>false</auto-increment> 
      <case-sensitive>true</case-sensitive> 
      <currency>false</currency> 
      <nullable>0</nullable> 
      <signed>false</signed> 
      <searchable>true</searchable> 
      <column-display-size>10</column-display-size> 
      <column-label>ID</column-label> 
      <column-name>ID</column-name> 
      <schema-name>ZHOUDP  </schema-name> 
      <column-precision>10</column-precision> 
      <column-scale>0</column-scale> 
      <table-name>STUDENT</table-name> 
      <catalog-name>TEST</catalog-name> 
      <column-type>12</column-type> 
      <column-type-name>VARCHAR</column-type-name> 
    </column-definition> 
    <column-definition> 
      <column-index>2</column-index> 
      <auto-increment>false</auto-increment> 
      <case-sensitive>true</case-sensitive> 
      <currency>false</currency> 
      <nullable>1</nullable> 
      <signed>false</signed> 
      <searchable>true</searchable> 
      <column-display-size>50</column-display-size> 
      <column-label>NAME</column-label> 
      <column-name>NAME</column-name> 
      <schema-name>ZHOUDP  </schema-name> 
      <column-precision>50</column-precision> 
      <column-scale>0</column-scale> 
      <table-name>STUDENT</table-name> 
      <catalog-name>TEST</catalog-name> 
      <column-type>12</column-type> 
      <column-type-name>VARCHAR</column-type-name> 
    </column-definition> 
  </metadata> 
  <data> 
    <currentRow> 
      <columnValue>0011</columnValue> 
      <columnValue>zhou</columnValue> 
    </currentRow> 
    <currentRow> 
      <columnValue>0021</columnValue> 
      <columnValue>zhang</columnValue> 
    </currentRow> 
  </data> 
 </webRowSet> 


关于作者

张黄瞩,zhanghuangzhu@gmail.com,熟悉 WBI Server Foundation, WPS 6.0,对Java,C/C++编程有浓厚的兴趣。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Java technology, Information Management
ArticleID=107667
ArticleTitle=使用 Java 5 RowSet 新特性访问 IBM DB2 数据库
publish-date=04102006
author1-email=zhanghuangzhu@gmail.com
author1-email-cc=

标签

Help
使用 搜索 文本框在 My developerWorks 中查找包含该标签的所有内容。

使用 滑动条 调节标签的数量。

热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。

我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。

使用搜索文本框在 My developerWorks 中查找包含该标签的所有内容。热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。