- 浏览: 58518 次
文章分类
最新评论
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
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可以通过调用populate(ResuletSet rs)来生成数据,一旦获得数据,CachedRowSet就可以断开与数据库的连接,直到往数据库写入数据的时候才需建立连接。
可以使用自己扩展的或是使用Reference Implement的实现类进行访问数据库。下面的代码演示了如何根据ResultSet建立一个CachedRowSet对象,在中断与数据库连接的情况下,读取数据,并做更新,最后再获取数据库连接,将更新落实到数据库中。
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发生改变时触发。其具体代码如下:
// 为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();
}
|
上面的程序的运行结果如下:
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功能与ResultSet类似,与CachedRowSet不同,JdbcRowSet在操作时保持与数据库的连接。可以将与数据库连接的URL,用户名,密码以及执行的SQL语句通过setXXX形式绑定。另外,JdbcRowSet返回的结果默认是可以上下滚动和可更新的,当然这需要数据库厂商提供的JDBC Driver支持。下面的代码演示了如何通过set方法设定数据库连接参数,以及如何操作JdbcRowSet对象。
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=0021,NAME=zhang
cursor moved
|
FilteredRowSet接口中规定了可以设定过滤器,其过滤接口为Predicate接口,必须实现Predicate接口中的evaluate方法。具体的代码如下:
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接口,其实现代码如下:
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;
}
}
|
其运行结果如下:
|
ID=0021,NAME=zhang
cursor moved
|
JoinRowSet可以将多个RowSet对象进行join合并,Join的列可以通过每个RowSet通过调用setMatchColumn方法来设置。setMatchColumn方式是Joinable接口定义的方法,五种类型的RowSet规定都需要实现该接口。下面的代码演示将student表和intern表中id相同的数据进行join操作。JoinRowSet不需要保持与数据库的连接。
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();
}
}
|
其输出结果为
|
|
WebRowSet继承自CachedRowSet,支持XML格式的查询,更新等操作,下面的代码将WebRowSet对象输出成XML格式到文件。
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文件属性格式
……
<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>
|
CachedRowSet 的使用
1向瘦客户端传递数据
使用 CachedRowSet
对象的主要原因之一是要在应用程序的不同组件之间传递数据。因为 CachedRowSet
对象是可序列化的,所以可使用它(举例来说)将运行于服务器环境的企业 JavaBeans 组件执行查询的结果通过网络发送到运行于 web 浏览器的客户端。
由于 CachedRowSet
对象是非连接的,所以和具有相同数据的 ResultSet
对象相比更为简洁。因此,它特别适于向瘦客户端(如 PDA)发送数据,这种瘦客户端由于资源限制或安全考虑而不适于使用 JDBC 驱动程序。所以 CachedRowSet
对象可提供一种“获取各行”的方式而无需实现全部 JDBC API。
2 滚动和更新
CachedRowSet
对象的第二个主要用途是为那些本身不提供滚动和更新的 ResultSet
对象提供这些功能。换句话说,当 DBMS 不提供对滚动和更新的完全支持时,可使用 CachedRowSet
对象扩充启用 JDBC 技术的驱动程序(以下称为“JDBC 驱动程序”)的功能。要使不可滚动和只读的 ResultSet
对象变得可滚动和可更新,程序员只需创建一个使用该 ResultSet
对象的数据所填充的 CachedRowSet
对象即可。以下代码片断演示了这一过程,其中 stmt
是一个 Statement
对象。
ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEES"); CachedRowSetImpl crs = new CachedRowSetImpl(); crs.populate(rs);
现在对象 crs
与对象 rs
一样,也包含了取自表 EMPLOYEES
的数据。不同的是 crs
的指针可以向前、向后移动,或者移动到特定行,即使 rs
的指针只能向前移动也是如此。此外,即使 rs
是不可更新的,crs
也将是可更新的,因为在默认情况下,CachedRowSet
对象是可滚动和可更新的。
总之,可将 CachedRowSet
对象简单地看成是一个非连接的行集合,这些行将缓存在数据源外部。由于它比较小并且是可序列化的,所以它可以轻松地通过导线发送,并且非常适合于向瘦客户端发送数据。但是 CachedRowSet
对象也有局限性:它的大小限制在它一次可在内存中存储的数据量范围内。
3 获得通用数据访问
CachedRowSet
类的另一个优势在于它能够从关系数据库以外各种数据源检索并存储数据。可以实现 rowset 的 reader 读取任何表格数据源(包括电子表格或平面文件)的数据,并用该数据填充其 rowset。因为 CachedRowSet
对象及其元数据都可以从头创建,所以充当 rowset 工厂的组件可以使用此功能来创建一个包含非 SQL 数据源数据的 rowset。但是,大部分情况下,希望 CachedRowSet
对象包含使用 JDBC API 从 SQL 数据库中获取的数据。
发表评论
-
oracle变量绑定
2012-06-18 19:18 598在JAVA 源程序中编写SQL语句时使用ORACLE 绑定变量 ... -
oracle的substr、length函数的用法
2012-05-27 11:19 3217oracle的substr函数的用法 ora ... -
Oracle 中 decode 函数用法
2012-04-26 20:10 574含义解释: decode(条件,值1,返回值1,值2,返回 ... -
plsql 查询报OCI错
2012-04-14 14:40 1242A query with lob's requires oci ... -
Java用OCI驱连Oracle数据库的实现方法
2012-04-14 14:37 2300在普通的情况下,用户 ...
相关推荐
sun.jdbc.rowset的jar包,2000年的老包。不过有些老项目需要。 包括sun.jdbc.rowset.CachedRowSet。
通过学习这个例子,开发者可以深入理解`JdbcRowSet`和`CachedRowSet`的使用场景和操作流程,提升在Java环境中处理数据库数据的能力。同时,这也是一种遵循JDBC最佳实践的方式,有助于编写更高效、更易于维护的代码。
- 将`ResultSet`传递给`CachedRowSet`,使用`acceptChanges`或`commit`方法提交更改。 - 可以使用`RowSetMetaData`来设置列信息,`RowSetEvent`和`RowSetListener`来监听ROWSET的变化。 ROWSet教程文件可能包含...
在给定的部分内容中,提到了使用`CachedRowSet`来操作数据库。`CachedRowSet`是Sun Microsystems为解决JDBC性能问题而引入的一种技术,它允许在内存中缓存ResultSet数据,从而可以在断开数据库连接的情况下对数据...
本文探讨了非连接行集在基于Java的B_S系统中的应用,介绍了一种基于JD BC 3.0的非连接行集接口CachedRowSet,利用该接口实例化的非连接行集对象,特别适合用于MVC模型中的表现层的开发。这种非连接行集可以在短暂...
第2部分 在两层客户/服务器结构中使用JDBC和SQL 第5章 使用JDBC和SQL创建表 5.1 创建数据库 5.2 使用表 5.2.1 记录和字段、行和列 5.2.2 SQL数据类型 5.2.3 完整性约束 5.3 创建表 5.4 使用JDBC创建表 ...
第2部分 在两层客户/服务器结构中使用JDBC和SQL 第5章 使用JDBC和SQL创建表 5.1 创建数据库 5.2 使用表 5.2.1 记录和字段、行和列 5.2.2 SQL数据类型 5.2.3 完整性约束 5.3 创建表 5.4 使用JDBC创建表 ...
第2部分 在两层客户/服务器结构中使用JDBC和SQL 第5章 使用JDBC和SQL创建表 5.1 创建数据库 5.2 使用表 5.2.1 记录和字段、行和列 5.2.2 SQL数据类型 5.2.3 完整性约束 5.3 创建表 5.4 使用JDBC创建表 ...
第2部分 在两层客户/服务器结构中使用JDBC和SQL 第5章 使用JDBC和SQL创建表 5.1 创建数据库 5.2 使用表 5.2.1 记录和字段、行和列 5.2.2 SQL数据类型 5.2.3 完整性约束 5.3 创建表 5.4 使用JDBC创建表 ...
这个接口包含了一些预定义的接口和类,如`CachedRowSet`和`WebRowSet`,它们为数据库操作提供了非常灵活和高效的方式。 1. **CachedRowSet**: 这是一个实现了滚动和遍历能力的接口,允许将结果集保存在内存中,即使...
- CachedRowSet:这是最基础的Rowset类型,它可以将数据缓存到内存中,支持离线操作。 - JoinRowSet:允许合并多个Rowset,实现跨表查询。 - FilteredRowSet:提供了基于谓词的过滤功能,可以筛选满足特定条件的...
- RowSet:介绍了CachedRowSet和JdbcRowSet的使用。 - 分布式事务支持:讲述了如何使用XA数据源、XA连接和XAResource来管理分布式事务。 ### 第5章 .NETDataProvider编程指南 - 数据类型:概述了.NET环境中使用的...
引入了javax.sql.rowset接口, 如CachedRowSet 和 WebRowSet. 可以在 JDK 1.2, 1.3, 和 1.4下使用.
1. CachedRowSet:这是最常见的RowSet实现,它可以在断开与数据库连接后保存和修改数据。CachedRowSet将数据存储在内存中,可以进行滚动、查找和编辑,然后再同步回数据库。 2. JdbcRowSet:它与数据库保持实时连接...
第七章涉及数据库操作,主要以SQL Server 2000为例,学习JDBC的使用,包括数据库连接、查询、更新、添加和删除操作,以及预处理语句和CachedRowSet分页显示技术。此外,还概述了连接Oracle和MySQL数据库的方法。 第...
下面是一个使用 `CachedRowSet` 的简单示例,该示例演示了如何从 SQL Server 数据库中获取数据,并在关闭数据库连接后继续进行数据处理。 ```java import java.sql.Connection; import java.sql.DriverManager; ...
- **6.2.3 CachedRowSet 类**:这部分讨论了CachedRowSet类的特点和使用方法。 ##### 6.3 数据库连接缓冲池 - 这部分介绍了数据库连接缓冲池的概念,以及如何使用连接池来提高数据库访问效率。 ##### 6.4 JNDI 和...
- **行集**:`javax.sql.rowset`包提供了一系列用于离线处理数据的类,如`CachedRowSet`。 - **分布式事务**:在分布式环境中协调多个资源(如数据库和消息队列)的事务管理。 #### 六、应用于JDBC的其他企业API -...