为DB2 XML数据开发Java应用程序
查询 XML 数据
既然知道了如何使用 Java 程序将 XML 数据插入 DB2 中,就可以开始查询 XML 数据了。本节中要详细介绍几个例子,从一个简单的任务(比如检索整个 XML 文档)开始,再前进到比较难的任务(比如基于 XML 和关系查询谓词返回部分 XML 文档)。
尽管 DB2 同时支持 SQL 和 XQuery 作为顶层语言,但是 XQuery 不提供解析参数标志符的手段。作为实际问题来讲,这意味着不仅仅需要硬编码查询谓词的应用程序中的任何 XQueries 都必须使用 SQL/XML 函数(XMLQuery 或 XMLExists)封装在一个 SQL 语句中。 "使用 SQL 查询 DB2 XML 数据"(developerWorks,2006 年 3 月)更详细地讨论了这些函数。在这里,您将看到如何在 Java 程序中使用它们。只是为了好玩,您将看到如何在应用程序中包含一个具有硬编码查询谓词的 XQuery。
检索完整的 XML 文档
我们的第一个基于查询的方法相当简单。它只检索一个给定客户的全部联系信息。这种自然的查询很容易用 SQL 来表达。所以,如果熟悉 JDBC,您应该容易理解该代码。
清单 7 中的 simpleQuery() 方法声明几个变量,然后使用 清单 2 中定义的 helper 方法建立一个数据库连接。query 字符串包含一个简单的 SQL 语句来选择指定客户的所有联系信息。执行该语句之后,应用程序输出已经取入字符串变量(stringDoc)中的结果。
清单 7. 利用 SQL 检索完整的 XML 文档
import java.sql.*;
. . .
public static void simpleQuery() {
PreparedStatement selectStmt = null;
String query = null, stringDoc = null;
ResultSet rs = null;
int clientID = 1885;
![]()
try{
// get a connection
Connection conn = Conn.getConn();
![]()
// define, prepare, and execute the query
// this will retrieve all XML data for a specific client
query = "select contactinfo from clients where id = " + clientID
selectStmt = conn.prepareStatement(query);
rs = selectStmt.executeQuery();
![]()
// check for results
if (rs.next() == false) {
System.out.println("Can't read document with id " + clientID);
}
![]()
// fetch XML data as a string and print the results
else {
stringDoc = rs.getString(1);
System.out.println(stringDoc);
}
. . .
conn.close();
}
catch (Exception e) { . . . }
}
该程序输出一行数据,其中包含指定客户的所有 XML 联系信息。
尽管这里没有展示,但是也可以使用 XQuery 来检索一个或多个完整的 XML 文档,假设您不需要在 XQuery 中合并参数标志符的话。在本文后面,您将看到一个 Java 摘录,其中使用 XQuery 来检索 XML 数据。
检索部分 XML 文档
检索部分 XML 文档是一个常见的编程任务。本例中的 Java 代码检索状态为 "Silver" 的客户的姓名和主电子邮件地址。客户姓名和状态信息存储在 SQL VARCHAR 列中,而电子邮件地址包含在 "contactinfo" 列中的 XML 文档中。
为简短起见,我们省略了前面展示的代码,只给出新的或不同的代码行。
清单 8. 利用 SQL/XML 检索关系数据和 XML 片段
. . .
String status = "Silver";
![]()
try{
// get a database connection
. . . .
// define, prepare, and execute a query that includes
// (1) a path expression that will return an XML element and
// (2) a parameter marker for a relational column value
String query = "SELECT name, xmlquery('$c/Client/email[1]' " +
" passing contactinfo as \"c\") " +
" from clients where status = ?";
PreparedStatement selectStmt = conn.prepareStatement(query);
selectStmt.setString(1, status);
ResultSet rs = selectStmt.executeQuery();
![]()
// iterate over and print the results
while(rs.next() ){
System.out.println("Name: " + rs.getString(1) +
" Email: " + rs.getString(2));
}
. . .
// release resources
}
catch (Exception e) { . . . }
该代码发出一个 SQL/XML 语句,该语句调用 XMLQuery 函数。它提供一个到该函数的路径表达式,导致 DB2 导航到目标 XML 文档的 "Client" 根元素下面的第一个 "email" 元素。(注意,路径表达式是大小写敏感的。)$c 变量和 SQL FROM 子句指出在哪里可以找到这些目标文档 —— 在 "clients" 表的 "contactinfo" 列中。SQL WHERE 子句进一步将目标 XML 文档限制为只在这样的行中找到的文档,这些行中客户的 "status" 是一个确定值(在本例中是 "Silver")。
该程序的输出类似于:
清单 9. 前一个应用程序的示例输出
Name: Lisa Hansen Email:
Name: Amy Liu Email: <email>sailer555@yahoo.com</email>
. . . .
在该示例输出中,没有返回符合条件的客户 (Lisa Hansen) 的电子邮件信息,因为该元素不存在于她的 XML "contactinfo" 文档中。
