中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> IBM专区 > DB2 > Java 技术
利用 DB2 UDB 来使用 WebRowSet 实现
作者:佚名 时间:2005-08-31 16:00 出处:互连网 责编:小渔
              摘要:利用 DB2 UDB 来使用 WebRowSet 实现
Java 1.5 为我们提供了使用 XML 表示和修改 DB2 数据的全新方法

级别: 初级

Kulvir Singh Bhogal
IBM Software Services for WebSphere, IBM Corporation
2005 年 4 月

WebRowSet 接口是 JSR-114 的产物,向我们提供了 Java™ 1.5 中的 JDBC™ Rowset 功能。RowSet 对象允许您与后端数据库在断开连接的情况下交互。本文着眼于由 javax.sql.RowSet 接口扩展而来的 WebRowSet,并向您展示如何利用 IBM® DB2® Universal Database™(DB2 UDB)来实现它。本文包含示例代码。

回顾 CachedRowSet
Java 1.5 向我们提供了 CachedRowSet 接口。CachedRowSet 对象允许我们从数据库中获取数据。此后,我们可以断开与数据库的连接,并在本地操作和浏览数据。要使我们对 CachedRowSet 对象做出的修改与数据库同步,只需连接到数据库并对所做的修改进行持久化处理(persistence)。您可以从我的 IBM developerWorks 文章(http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0406bhogal/)学习到更多关于 CachedRowSet 接口的知识。在这篇文章中,我们将学习 WebRowSet 对象,我建议您在阅读本文之前,先阅读我关于 CachedRowSet 的文章,熟悉一下 CachedRowSet

WebRowSet
WebRowSet 接口由 CachedRowSet 接口扩展而来。与其父接口一样,WebRowSet 也可被串行化。这种串行化能力使我们可以通过线路发送 WebRowSet 对象(对于过去的 ResultSet 来说这是不可能的),这使得 WebRowSet 对象特别适合用于设置企业 Java Bean(Enterprise Java Bean,EJB)。WebRowSet 增加的一个主要价值就是能够将 WebRowSet 对象写成 XML 文档。不久您将会发现,您可以从格式良好的 XML 文档填充 WebRowSet 对象。

本文中,我将告诉您如何使用 WebRowSet 接口。关于后端数据库,我们将使用 IBM DB2 Universal Database Version 8,您可以在http://www14.software.ibm.com/webapp/download/home.jsp 下载到试用版。特别提醒,在我们的学习中,您需要使用 Java 1.5。此外,如果您希望使用文中展示的 WebRowSet 接口和 Sun 的参考实现,您可以在 http://java.sun.com/products/jdbc/download.html 单独下载该参考实现。

为我们的学习准备好 DB2 UDB
为了开始学习,我们首先创建一个只包含一张表的简单数据库。为此,我们需要使用 DB2 命令行处理程序创建一个名为 webrowex 的数据库:


            db2 => create database webrowex
            

使用您的用户名和密码连接这个数据库(这里,我的用户名是“db2admin”,密码为“db2admin):


            db2 => connect to webrowex user db2admin using db2admin
            

我们的表是一个叫做 convert 的简单的表,其中包含公制与美制计量单位的换算因子。

表 1. 转换因子
转换 转换因子
CentimeterToInch 0.39
KilometerToMile 0.62
PoundToKilogram 0.45

利用 SQL,我们可以这样来创建表:


            db2 => create table convert (conversion varchar(80)
            primary key not null, factor decimal (6,2) NOT NULL)
            

继续在表中插入值:


            db2 => insert into convert values(‘CentimeterToInch’,0.39)
            db2 => insert into convert values(‘KilometerToMile’,0.62)
            db2 => insert into convert values(‘PoundToKilogram’,0.45)
            

填充 WebRowSet
现在,数据库已经就位,可以开始处理 WebRowSet 了。javax.sql.rowset.WebRowSet 是一个 Java 接口。要演示 WebRowSet 对象,我们用 com.sun.rowset.WebRowSetImpl 实现来示范:


            WebRowSet conversionFactors = new WebRowSetImpl();
            

此时,WebRowSet 对象还是空的。我们需要向其填充数据。这里有两种方法可供选择。一种是使用 WebRowSet 对象来建立数据库连接:


            WebRowSet conversionFactors = new WebRowSetImpl();
            conversionFactors.setUrl("jdbc:db2://localhost:50000/webrowex");
            conversionFactors.setUsername("db2admin");
            conversionFactors.setPassword("db2admin");
            conversionFactors.setCommand("SELECT * FROM CONVERT");
            conversionFactors.execute();
            

另一种方法是使用 ResultSet 对象来填充 WebRowSet 对象:


            // load the DB2 Driver
            Class.forName("com.ibm.db2.jcc.DB2Driver");
            Connection db2Conn =
            DriverManager.getConnection("jdbc:db2://localhost:50000/webrowex",
            "db2admin","db2admin");
            // use a statement to gather data from the database
            Statement st = db2Conn.createStatement();
            String myQuery = "SELECT * FROM CONVERT";
            WebRowSet conversionFactors = new WebRowSetImpl();
            // execute the query
            ResultSet resultSet = st.executeQuery(myQuery);
            conversionFactors.populate(resultSet);
            

事先说明,当使用由 ResultSet 对象填充得到的 WebRowSet 对象的 acceptChanges 方法时(本文后面将会介绍),您需要使用带有 java.sql.Connection 对象参数的 acceptChanges 方法,该参数表示用于创建 ResultSet 的数据库连接。

写入 XML
WebRowSet 对象写入 XML 再简单不过了。我们只需使用 writeXML 方法即可,它既可以接受 OutputStream 对象(如果我们以二进制字节写入),也可以接受 Writer 对象(如果我们用字符写入)。下面的代码片断将使用 FileWriter 对象写入到一个叫做 conversions.xml 的文件。


            java.io.FileWriter writer = new java.io.FileWriter("c:\\conversions.xml");
            conversionFactors.writeXml(writer);
            

上面的代码摘自示例类 WebRowSetExample.java,您可以连同本文一起下载。在执行这个类之后,您需要花些时间来看看文件 conversions.xml,了解我们抓取并填充到 WebRowSet 对象中的数据是如何表示为 XML 的。通过分析 XML 文件,我们知道它包含了有关表和列(我们从中抓取数据)的结构和数据本身的元数据。这个 XML 文件实际上是根据已经成为 WebRowSet XML schema 定义(参阅 http://java.sun.com/xml/ns/jdbc/webrowset.xsd)的规则来构造的。最酷的是,您根本无须了解错综复杂的 XML 模式,所有一切都已在幕后为您完成了。

总之,XML 文档要包含一个属性部分(如下所示),含有我们的连接信息,包括与 WebRowSet 关联的命令 SELECT * FROM CONVERT,以及用于连接至数据库的 URL:jdbc:db2://localhost:50000/webrowex


            <properties>
            <command>SELECT * FROM CONVERT</command>
            <concurrency>1008</concurrency>
            <datasource><null/></datasource>
            <escape-processing>true</escape-processing>
            <fetch-direction>1000</fetch-direction>
            <fetch-size>0</fetch-size>
            <isolation-level>2</isolation-level>
            <key-columns>
            </key-columns>
            <map>
            </map>
            <max-field-size>0</max-field-size>
            <max-rows>0</max-rows>
            <query-timeout>0</query-timeout>
            <read-only>true</read-only>
            <rowset-type>ResultSet.TYPE_SCROLL_INSENSITIVE</rowset-type>
            <show-deleted>false</show-deleted>
            <table-name>CONVERT</table-name>
            <url>jdbc:db2://localhost:50000/webrowex</url>
            <sync-provider>
            <sync-provider-name>com.sun.rowset.providers.RIOptimisticProvider</sync-provider-name>
            <sync-provider-vendor>Sun Microsystems Inc.</sync-provider-vendor>
            <sync-provider-version>1.0</sync-provider-version>
            <sync-provider-grade>2</sync-provider-grade>
            <data-source-lock>1</data-source-lock>
            </sync-provider>
            </properties>
            

元数据部分(如下所示)包含关于列的结构的元数据,这些列组成了 WebRowSet 对象。如果您还记得,我们的查询是 SELECT * FROM CONVERTCONVERT 表包含名为 CONVERSIONFACTOR 的列,两个列的结构都是在 metadata 部分中描述的。您会看到,每个列都有一个 <column-definition> 元素,用于描述底层列的结构。例如,对于我们的第一个列,即 CONVERSION 列,诸如模式名(DB2ADMIN)、列类型(VARCHAR) 以及列精度(80)等信息都进行了描述。


            <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>80</column-display-size>
            <column-label>CONVERSION</column-label>
            <column-name>CONVERSION</column-name>
            <schema-name>DB2ADMIN</schema-name>
            <column-precision>80</column-precision>
            <column-scale>0</column-scale>
            <table-name>CONVERT</table-name>
            <catalog-name>WEBROWEX</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>false</case-sensitive>
            <currency>false</currency>
            <nullable>0</nullable>
            <signed>true</signed>
            <searchable>true</searchable>
            <column-display-size>8</column-display-size>
            <column-label>FACTOR</column-label>
            <column-name>FACTOR</column-name>
            <schema-name>DB2ADMIN</schema-name>
            <column-precision>6</column-precision>
            <column-scale>2</column-scale>
            <table-name>CONVERT</table-name>
            <catalog-name>WEBROWEX</catalog-name>
            <column-type>3</column-type>
            <column-type-name>DECIMAL</column-type-name>
            </column-definition>
            </metadata>
            

我们的 XML 中的最后(但并非最不重要)是一个 data 部分,如下所示。如您所见,每个 <currentRow> 元素包含两个 <columnValue> 元素以及包含在它们中的数据。这些子元素的顺序必须严格对应于 metadata 部分描述的列顺序。


            <data>
            <currentRow>
            <columnValue>CentimeterToInch</columnValue>
            <columnValue>0.39</columnValue>
            </currentRow>
            <currentRow>
            <columnValue>KilometerToMile</columnValue>
            <columnValue>0.62</columnValue>
            </currentRow>
            <currentRow>
            <columnValue>PoundToKilogram</columnValue>
            <columnValue>0.45</columnValue>
            </currentRow>
            </data>
            

进行修改
如果我们在本地修改 WebRowSet(例如,插入、更新或删除行),生成的 XML 文件表示将包含修改信息。我们下面就来看看这个。

插入行
正如我在本文前一篇文章中提到的 CachedRowSet 一样,要执行插入,首先应将光标移动到名为“insert row”的特定区域。然后,我们可以用“父(更确切地说是‘祖父’)ResultSet 接口”给予我们的更新方法来填充新行。当我们使用 insertRow() 方法时,WebRowSet 对象就被更新。实际的改变是在执行 acceptChanges() 方法时才持久存储到数据库的。以下代码摘自 WebRowSetExample.java,演示了该过程:


            // move the cursor to a blank row
            conversionFactors.moveToInsertRow();
            // populate the new row
            conversionFactors.updateString(1,"MeterToYard");
            conversionFactors.updateDouble(2,1.19d);
            // insert the new row
            conversionFactors.insertRow();
            // move cursor back to previous position
            conversionFactors.moveToCurrentRow();
            

WebRowSetExample.java 中,我故意在插入行之后和调用 acceptChanges 方法之前写入另一个 XML 文件 conversionsinsert.xml,使您可以在每个用例后对比生成的 XML 文件。


            <data>
            <currentRow>
            <columnValue>CentimeterToInch</columnValue>
            <columnValue>0.39</columnValue>
            </currentRow>
            <currentRow>
            <columnValue>KilometerToMile</columnValue>
            <columnValue>0.62</columnValue>
            </currentRow>
            <currentRow>
            <columnValue>PoundToKilogram</columnValue>
            <columnValue>0.45</columnValue>
            </currentRow>
            <insertRow>
            <columnValue>MeterToYard</columnValue>
            <columnValue>1.19</columnValue>
            </insertRow>
            </data>
            

注意 <data> 元素是如何包含 <insertRow> 元素的(上面的蓝色部分),后者对应于我们试图插入 WebRowSet 的新行。

删除行
要删除 WebRowSet 中的一行,我们可以将光标定位于要使用 absolute 方法删除的行,然后使用 WebRowSet 对象的 deleteRow() 方法。例如,要删除 KilometerToMile 行(我们 WebRowSet 中的第二行),我们使用如下代码:


            conversionFactors.absolute(2);
            conversionFactors.deleteRow();
            

在我的示例代码中,我还写入了另一个 XML 文件(conversionsdelete.xml),以展示 WebRowSet 是如何以 XML 格式表示数据修改的。


            <data>
            <currentRow>
            <columnValue>CentimeterToInch</columnValue>
            <columnValue>0.39</columnValue>
            </currentRow>
            <deleteRow>
            <columnValue>KilometerToMile</columnValue>
            <columnValue>0.62</columnValue>
            </deleteRow>
            <currentRow>
            <columnValue>PoundToKilogram</columnValue>
            <columnValue>0.45</columnValue>
            </currentRow>
            <insertRow>
            <columnValue>MeterToYard</columnValue>
            <columnValue>1.19</columnValue>
            </insertRow>
            </data>
            

注意,我们从上面的 conversionsdelete.xml 抓取的数据元素 I 中包含一个新的元素,叫做 <deleteRow>(上面的红色部分),它表示我们想要删除哪一行。另外要注意,这里仍然存在 <insertRow> 元素,因为在执行这段示例代码的时候,我们还没有使用 acceptChanges 方法。换言之,我们还没有使 WebRowSet 与数据库同步。

修改行
倘若您是个细心的人,把所有转换因子都记在脑海里,您可能注意到了,我曾经告诉过您,从米到码(MeterToYard)的转换因子是 1.19 而不是 1.09。我当然知道我弄错了,我只是为介绍 WebRowSet 的更新功能而打下铺垫。下面这段代码将设置 FACTOR 列的值为 1.09,从而更新 CONVERSION 列的值为 MeterToYard 的这一行。


            conversionFactors.absolute(4);
            conversionFactors.updateDouble("factor",1.09d);
            

注意我必须把光标移至 4 而并非 3,因为虽然我们删除了一行,但是仍需迭代它存在的位置,这是由于前面的修改还未生效(另一方面,也是因为还没有进行同步操作)。

像前面那样,我把产生的 XML 转储到一个文件。在本例中,该文件是 conversionsmodify.xml。下面的 XML 就提取于这个文件:


            <data>
            <currentRow>
            <columnValue>CentimeterToInch</columnValue>
            <columnValue>0.39</columnValue>
            </currentRow>
            <deleteRow>
            <columnValue>KilometerToMile</columnValue>
            <columnValue>0.62</columnValue>
            </deleteRow>
            <currentRow>
            <columnValue>PoundToKilogram</columnValue>
            <columnValue>0.45</columnValue>
            </currentRow>
            <insertRow>
            <columnValue>MeterToYard</columnValue>
            <columnValue>1.19</columnValue>
<updateRow>1.09</updateRow>
</insertRow> </data>

注意,标记为红色的 <deleteRow> 标签仍然存在,因为就像刚才提到的,我们还未提交所做的修改。此外,如果您还记得,我们添加了从米到码的转换行。由于修改尚未被持久存储,所以 <updateRow> 元素作为 <insertRow> 元素的一部分被嵌入其中(复合效果)。如果我们使用 acceptChanges 方法同步了所做的修改,则不是 <updateRow> 元素嵌套在 <insertRow> 元素内了,我们会看到:


            <currentRow>
            <columnValue>MeterToYard</columnValue>
            <columnValue>1.19</columnValue>
            <updateRow>1.09</updateRow>
            </currentRow>
            

注意 WebRowSet 是如何追踪数据中的新旧值的。这对于了解是否有其他客户机在尝试修改我们在本地缓存中想要修改的数据很重要。

数据完整性乐观论
如我在文章 "断开连接" 中提到的 CachedRowSet 实现一样,Sun 提供的 WebRowSet 实现对数据完整性采取乐观的方法。WebRowSet 并不在数据库服务器上设置锁。因此,如果您想在本地修改一个行,而当您最后进行同步的时候发现其他客户机应用程序删除或修改了这一行,那么系统会抛出一个同步异常。当您查看您正在研究的 XML 文件中的 properties 部分时,您会看到相应的元素:


            <sync-provider-name>
            com.sun.rowset.providers.RIOptimisticProvider
            </sync-provider-name>
            

com.sun.rowset.providers.RIOptimisticProvider 指的是 WebRowset 实现将要使用的乐观的提供者。

利用 XML
至此,我已经向您展示了如何从 WebRowSet 对象写入 XML。利用 WebRowSet,我们也可以将 XML 文件的内容填充到 WebRowSet 对象。readXML 方法可以接受 javai.io.FileReader 对象,并填充 WebRowSet 对象。下面这个代码片断演示了该如何去做这件事情:


            // instantiate a WebRowSet object
            WebRowSet webRowSet = new WebRowSetImpl();
            FileReader reader = new FileReader("c:\\conversionsfinish.xml");
            // populate the WebRowSet object with the contents of the XML file
            webRowSet.readXML(reader);
            

从上面的代码可以获悉,因为能够以预定义的 XML 格式(如 WebRowSet XML Schema 所规定的)填充 WebRowSet 对象,所以我们完全拥有以自我描述的格式来填充数据库的强大选择权。

结束语
在 XML 中,WebRowSet 的自我描述特性使其非常适合于以 XML 为中心的技术,比如 Web 服务。同样,因为能够将 WebRowSet 表示为 XML,所以我们可以轻松地将 XML 发送到网络客户机。您可以使用 XSLT 将 XML 文档转换成 Web 浏览器或移动设备(如 PDA 和移动电话等)可以浏览的格式。此外,终端客户机亦可以选择将数据库中的数据进行本地存储,以进行归档。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有