Documentation

The Java™ Tutorials
Hide TOC
Using WebRowSet Objects使用WebRowSet对象
Trail: JDBC Database Access
Lesson: JDBC Basics

Using WebRowSet Objects使用WebRowSet对象

A WebRowSet object is very special because in addition to offering all of the capabilities of a CachedRowSet object, it can write itself as an XML document and can also read that XML document to convert itself back to a WebRowSet object. WebRowSet对象非常特殊,因为它除了提供CachedRowSet对象的所有功能外,还可以将自身编写为XML文档,还可以读取该XML文档以将自身转换回WebRowSet对象。Because XML is the language through which disparate enterprises can communicate with each other, it has become the standard for Web Services communication. 由于XML是不同企业之间可以相互通信的语言,因此它已成为Web服务通信的标准。As a consequence, a WebRowSet object fills a real need by enabling Web Services to send and receive data from a database in the form of an XML document.因此,WebRowSet对象通过使Web服务能够以XML文档的形式从数据库发送和接收数据来满足实际需要。

The following topics are covered:涵盖以下主题:

The Coffee Break company has expanded to selling coffee online. 这家咖啡休息公司已经扩展到在线销售咖啡。Users order coffee by the pound from the Coffee Break Web site. 用户从咖啡休息网站上按磅订购咖啡。The price list is regularly updated by getting the latest information from the company's database. 通过从公司数据库获取最新信息,定期更新价目表。This section demonstrates how to send the price data as an XML document with a WebRowSet object and a single method call.本节演示如何使用WebRowSet对象和单个方法调用将价格数据作为XML文档发送。

Creating and Populating WebRowSet Objects创建和填充WebRowSet对象

You create a new WebRowSet object by using an instance of RowSetFactory, which is created from the RowSetProvider class, to create a WebRowSet object. 通过使用从RowSetProvider类创建的RowSetFactory实例来创建WebRowSet对象,可以创建一个新的WebRowSet对象。The following example is from WebRowSetSample:以下示例来自WebRowSetSample

RowSetFactory factory = RowSetProvider.newFactory();  
    try (WebRowSet priceList = factory.createWebRowSet();
         // ...
    ) {	  
      // ...

Although the priceList object has no data yet, it has the default properties of a BaseRowSet object. Its SyncProvider object is at first set to the RIOptimisticProvider implementation, which is the default for all disconnected RowSet objects. However, the WebRowSet implementation resets the SyncProvider object to be the RIXMLProvider implementation.

You can use an instance of RowSetFactory, which is created from the RowSetProvider class, to create a WebRowSet object. See Using the RowSetFactory Interface in Using JdbcRowSet Objects for more information.

The Coffee Break headquarters regularly sends price list updates to its web site. 咖啡休息时间总部定期向其网站发送最新价目表。This information on WebRowSet objects will show one way you can send the latest price list in an XML document.有关WebRowSet对象的信息将显示一种在XML文档中发送最新价目表的方法。

The price list consists of the data in the columns COF_NAME and PRICE from the table COFFEES. The following code fragment sets the properties needed and populates the priceList object with the price list data:

int[] keyCols = {1};
      priceList.setUsername(settings.userName);
      priceList.setPassword(settings.password);
      priceList.setUrl(settings.urlString);
      priceList.setCommand("select COF_NAME, PRICE from COFFEES");
      priceList.setKeyColumns(keyCols);

      // Populate the WebRowSet
      priceList.execute();

At this point, in addition to the default properties, the priceList object contains the data in the COF_NAME and PRICE columns from the COFFEES table and also the metadata about these two columns.

Writing and Reading WebRowSet Object to XML将WebRowSet对象写入和读取为XML

To write a WebRowSet object as an XML document, call the method writeXml. 要将WebRowSet对象写入XML文档,请调用writeXml方法。To read that XML document's contents into a WebRowSet object, call the method readXml. 要将该XML文档的内容读入WebRowSet对象,请调用readXml方法。Both of these methods do their work in the background, meaning that everything, except the results, is invisible to you.这两种方法都是在后台工作的,这意味着除了结果之外,任何东西都是你看不见的。

Using the writeXml Method使用writeXml方法

The method writeXml writes the WebRowSet object that invoked it as an XML document that represents its current state. writeXml方法将调用它的WebRowSet对象写入表示其当前状态的XML文档。It writes this XML document to the stream that you pass to it. 它将这个XML文档写入您传递给它的流中。The stream can be an OutputStream object, such as a FileOutputStream object, or a Writer object, such as a FileWriter object. If you pass the method writeXml an OutputStream object, you will write in bytes, which can handle all types of data; if you pass it a Writer object, you will write in characters. The following code demonstrates writing the WebRowSet object priceList as an XML document to the FileOutputStream object oStream:

java.io.FileOutputStream oStream =
    new java.io.FileOutputStream("priceList.xml");
priceList.writeXml(oStream);

The following code writes the XML document representing priceList to the FileWriter object writer instead of to an OutputStream object. The FileWriter class is a convenience class for writing characters to a file.

java.io.FileWriter writer =
    new java.io.FileWriter("priceList.xml");
priceList.writeXml(writer);

The other two versions of the method writeXml let you populate a WebRowSet object with the contents of a ResultSet object before writing it to a stream. In the following line of code, the method writeXml reads the contents of the ResultSet object rs into the priceList object and then writes priceList to the FileOutputStream object oStream as an XML document.

priceList.writeXml(rs, oStream);

In the next line of code, the writeXml methodpopulates priceList with the contents of rs, but it writes the XML document to a FileWriter object instead of to an OutputStream object:

priceList.writeXml(rs, writer);

Using the readXml Method使用readXml方法

The method readXml parses an XML document in order to construct the WebRowSet object the XML document describes. Similar to the method writeXml, you can pass readXml an InputStream object or a Reader object from which to read the XML document.

java.io.FileInputStream iStream =
    new java.io.FileInputStream("priceList.xml");
priceList.readXml(iStream);

java.io.FileReader reader = new
    java.io.FileReader("priceList.xml");
priceList.readXml(reader);

Note that you can read the XML description into a new WebRowSet object or into the same WebRowSet object that called the writeXml method. In the scenario, where the price list information is being sent from headquarters to the Web site, you would use a new WebRowSet object, as shown in the following lines of code:在将价目表信息从总部发送到网站的场景中,您将使用新的WebRowSet对象,如以下代码行所示:

WebRowSet recipient = new WebRowSetImpl();
java.io.FileReader reader = new java.io.FileReader("priceList.xml");
recipient.readXml(reader);

What Is in XML DocumentsXML文档中有什么

RowSet objects are more than just the data they contain. RowSet对象不仅仅是它们包含的数据。They have properties and metadata about their columns as well. 它们也有关于其列的属性和元数据。Therefore, an XML document representing a WebRowSet object includes this other information in addition to its data. 因此,表示WebRowSet对象的XML文档除了其数据之外还包含其他信息。Further, the data in an XML document includes both current values and original values. 此外,XML文档中的数据包括当前值和原始值。(Recall that original values are the values that existed immediately before the most recent changes to data were made. (请记住,原始值是在最近对数据进行更改之前存在的值。These values are necessary for checking if the corresponding value in the database has been changed, thus creating a conflict over which value should be persistent: the new value you put in the RowSet object or the new value someone else put in the database.)这些值对于检查数据库中的相应值是否已更改是必需的,从而在哪些值应保持不变方面产生冲突:您在RowSet对象中输入的新值或其他人在数据库中输入的新值。)

The WebRowSet XML Schema, itself an XML document, defines what an XML document representing a WebRowSet object will contain and also the format in which it must be presented. WebRowSet XML模式本身就是一个XML文档,它定义了表示WebRowSet对象的XML文档将包含的内容以及它必须以何种格式显示。Both the sender and the recipient use this schema because it tells the sender how to write the XML document (which represents the WebRowSet object) and the recipient how to parse the XML document. 发送方和接收方都使用此模式,因为它告诉发送方如何编写XML文档(表示WebRowSet对象)和接收方如何解析XML文档。Because the actual writing and reading is done internally by the implementations of the methods writeXml and readXml, you, as a user, do not need to understand what is in the WebRowSet XML Schema document.因为实际的写入和读取是通过writeXmlreadXml方法的实现在内部完成的,所以作为用户,您不需要理解WebRowSet XML模式文档中的内容。

XML documents contain elements and subelements in a hierarchical structure. XML文档包含层次结构中的元素和子元素。The following are the three main elements in an XML document describing a WebRowSet object:以下是描述WebRowSet对象的XML文档中的三个主要元素:

Element tags signal the beginning and end of an element. 元素标记表示元素的开始和结束。For example, the <properties> tag signals the beginning of the properties element, and the </properties> tag signals its end. 例如,<properties>标记表示属性元素的开头,</properties>标签标志着它的结束。The <map/> tag is a shorthand way of saying that the map subelement (one of the subelements in the properties element) has not been assigned a value. The following sample XML documents uses spacing and indentation to make it easier to read, but those are not used in an actual XML document, where spacing does not mean anything.

The next three sections show you what the three main elements contain for the WebRowSet priceList object, created in the sample WebRowSetSample.

Properties性质

Calling the method writeXml on the priceList object would produce an XML document describing priceList. The properties section of this XML document would look like the following:此XML文档的属性部分如下所示:

<properties>
 <command> select COF_NAME, PRICE from COFFEES
</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>
 <column>1</column>
 </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>COFFEES</table-name>
 <url>jdbc:mysql://localhost:3306/testdb</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>

Notice that some properties have no value. For example, the datasource property is indicated with the <datasource/> tag, which is a shorthand way of saying <datasource></datasource>. No value is given because the url property is set. Any connections that are established will be done using this JDBC URL, so no DataSource object needs to be set. Also, the username and password properties are not listed because they must remain secret.

Metadata

The metadata section of the XML document describing a WebRowSet object contains information about the columns in that WebRowSet object. The following shows what this section looks like for the WebRowSet object priceList. Because the priceList object has two columns, the XML document describing it has two <column-definition> elements. Each <column-definition> element has subelements giving information about the column being described.

<metadata>
 <column-count>2</column-count>
 <column-definition>
 <column-index>1</column-index>
 <auto-increment>false</auto-increment>
 <case-sensitive>false</case-sensitive>
 <currency>false</currency>
 <nullable>0</nullable>
 <signed>false</signed>
 <searchable>true</searchable>
 <column-display-size> 32</column-display-size>
 <column-label>COF_NAME</column-label>
 <column-name>COF_NAME</column-name>
 <schema-name></schema-name>
 <column-precision>32</column-precision>
 <column-scale>0</column-scale>
 <table-name>coffees</table-name>
 <catalog-name>testdb</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>0</nullable>
 <signed>true</signed>
 <searchable>true</searchable>
 <column-display-size> 12</column-display-size>
 <column-label>PRICE</column-label>
 <column-name>PRICE</column-name>
 <schema-name></schema-name>
 <column-precision>10</column-precision>
 <column-scale>2</column-scale>
 <table-name>coffees</table-name>
 <catalog-name>testdb</catalog-name>
 <column-type>3</column-type>
 <column-type-name> DECIMAL</column-type-name>
 </column-definition>
</metadata>

From this metadata section, you can see that there are two columns in each row. 从这个元数据部分,您可以看到每行中有两列。The first column is COF_NAME, which holds values of type VARCHAR. 第一列是COF_NAME,它保存VARCHAR类型的值。The second column is PRICE, which holds values of type REAL, and so on. Note that the column types are the data types used in the data source, not types in the Java programming language. To get or update values in the COF_NAME column, you use the methods getString or updateString, and the driver makes the conversion to the VARCHAR type, as it usually does.

Data

The data section gives the values for each column in each row of a WebRowSet object. If you have populated the priceList object and not made any changes to it, the data element of the XML document will look like the following. In the next section you will see how the XML document changes when you modify the data in the priceList object.在下一节中,您将看到修改priceList对象中的数据时XML文档是如何变化的。

For each row there is a <currentRow> element, and because priceList has two columns, each <currentRow> element contains two <columnValue> elements.

<data>
 <currentRow>
 <columnValue>Colombian</columnValue>
 <columnValue>7.99</columnValue>
 </currentRow>
 <currentRow>
 <columnValue> Colombian_Decaf</columnValue>
 <columnValue>8.99</columnValue>
 </currentRow>
 <currentRow>
 <columnValue>Espresso</columnValue>
 <columnValue>9.99</columnValue>
 </currentRow>
 <currentRow>
 <columnValue>French_Roast</columnValue>
 <columnValue>8.99</columnValue>
 </currentRow>
 <currentRow>
 <columnValue>French_Roast_Decaf</columnValue>
 <columnValue>9.99</columnValue>
 </currentRow>
</data>

Making Changes to WebRowSet Objects对WebRowSet对象进行更改

You make changes to a WebRowSet object the same way you do to a CachedRowSet object. Unlike a CachedRowSet object, however, a WebRowSet object keeps track of updates, insertions, and deletions so that the writeXml method can write both the current values and the original values. The three sections that follow demonstrate making changes to the data and show what the XML document describing the WebRowSet object looks like after each change. You do not have to do anything at all regarding the XML document; any change to it is made automatically, just as with writing and reading the XML document.您不必对XML文档做任何事情;对它的任何更改都是自动进行的,就像编写和读取XML文档一样。

Inserting Rows插入行

If the owner of the Coffee Break chain wants to add a new coffee to the price list, the code might look like this:如果咖啡连锁店的所有者希望将新咖啡添加到价目表中,代码可能如下所示:

priceList.absolute(3);
priceList.moveToInsertRow();
priceList.updateString(COF_NAME, "Kona");
priceList.updateFloat(PRICE, 8.99f);
priceList.insertRow();
priceList.moveToCurrentRow();

In the reference implementation, an insertion is made immediately following the current row. 在引用实现中,插入紧跟在当前行之后。In the preceding code fragment, the current row is the third row, so the new row would be added after the third row and become the new fourth row. 在前面的代码片段中,当前行是第三行,因此新行将添加到第三行之后,并成为新的第四行。To reflect this insertion, the XML document would have the following <insertRow> element added to it after the third <currentRow> element in the <data> element.为了反映这种插入,XML文档将在<data>元素中的第三个<currentRow>元素后面添加<insertRow>元素。

The <insertRow> element will look similar to the following.这个<insertRow>元素将类似于以下内容。

<insertRow>
 <columnValue>Kona</columnValue>
 <columnValue>8.99</columnValue>
</insertRow>

Deleting Rows删除行

The owner decides that Espresso is not selling enough and should be removed from the coffees sold at The Coffee Break shops. 店主认为浓缩咖啡销量不足,应将其从咖啡休息店出售的咖啡中删除。The owner therefore wants to delete Espresso from the price list. 因此,店主希望从价目表中删除浓缩咖啡。Espresso is in the third row of the priceList object, so the following lines of code delete it:Espresso位于priceList对象的第三行,因此以下代码行将其删除:

priceList.absolute(3); priceList.deleteRow();

The following <deleteRow> element will appear after the second row in the data section of the XML document, indicating that the third row has been deleted.以下是<deleteRow>元素将出现在XML文档数据部分的第二行之后,表示第三行已被删除。

<deleteRow>
 <columnValue>Espresso</columnValue>
 <columnValue>9.99</columnValue>
</deleteRow>

Modifying Rows修改行

The owner further decides that the price of Colombian coffee is too expensive and wants to lower it to $6.99 a pound. 店主进一步认为哥伦比亚咖啡的价格太贵,希望将其降至$6.99英镑。The following code sets the new price for Colombian coffee, which is in the first row, to $6.99 a pound:以下代码将位于第一行的哥伦比亚咖啡的新价格设置为每磅$6.99英镑:

priceList.first();
priceList.updateFloat(PRICE, 6.99);

The XML document will reflect this change in an <updateRow> element that gives the new value. XML文档将在<updateRow>提供新值的元素。The value for the first column did not change, so there is an <updateValue> element only for the second column:第一列的值没有更改,因此存在<updateValue>元素仅用于第二列:

<currentRow>
 <columnValue>Colombian</columnValue>
 <columnValue>7.99</columnValue>
 <updateRow>6.99</updateRow>
</currentRow>

At this point, with the insertion of a row, the deletion of a row, and the modification of a row, the XML document for the priceList object would look like the following:此时,插入行、删除行和修改行后,priceList对象的XML文档将如下所示:

<data>
 <insertRow>
 <columnValue>Kona</columnValue>
 <columnValue>8.99</columnValue>
 </insertRow>
 <currentRow>
 <columnValue>Colombian</columnValue>
 <columnValue>7.99</columnValue>
 <updateRow>6.99</updateRow>
 </currentRow>
 <currentRow>
 <columnValue> Colombian_Decaf</columnValue>
 <columnValue>8.99</columnValue>
 </currentRow>
 <deleteRow>
 <columnValue>Espresso</columnValue>
 <columnValue>9.99</columnValue>
 </deleteRow>
 <currentRow>
 <columnValue>French_Roast</columnValue>
 <columnValue>8.99</columnValue>
 </currentRow>
 <currentRow>
 <columnValue> French_Roast_Decaf</columnValue>
 <columnValue>9.99</columnValue>
 </currentRow>
</data>

WebRowSet Code ExampleWebRowSet代码示例

The sample WebRowSetSample.java demonstrates all the features described on this page.示例WebRowSetSample.java演示了本页中描述的所有功能。


Previous page: Using FilteredRowSet Objects
Next page: Using Advanced Data Types