技术开发 频道

为DB2 XML数据开发Java应用程序

    根据关系谓词和 XML 谓词进行过滤

    Java 程序也可以指示 DB2 基于适合于 XML 和非 XML 数据的条件来过滤查询输出。下面这个例子构建在前一个例子的基础之上,返回居住在加利福尼亚州圣何塞的 "Silver" 客户的姓名和主电子邮件地址。这个简单的查询从 XML 和非 XML 列检索数据,还基于 XML 和非 XML 列的内容限制数据。

    下面这个摘录只包含从前一个例子发生了改变的部分代码。在本例中,SELECT 语句现在调用 XMLExists 作为 WHERE 子句的一部分,以限制居住在指定城市和州(分别在 city 和 state 变量中定义)的客户的结果。

    清单 10. 基于 XML 元素值过滤 XML 数据

. . . String status = "Silver"; String state = "CA"; String city = "San Jose"; . . . try{ . . . . String query = "SELECT name, xmlquery('$c/Client/email[1]' " + " passing contactinfo as \"c\") " + " from clients where status = ?" " and xmlexists('$c/Client/Address[state=$state][city=$city]' " + " passing contactinfo as \"c\", " + " cast(? as char(2)) as \"state\", " + " cast(? as varchar(30)) as \"city\" )"; PreparedStatement selectStmt = conn.prepareStatement(query); selectStmt.setString(1, status); selectStmt.setString(2, state); selectStmt.setString(3, city); . . . }

    该查询的大部分您应该已经熟悉,所以本节只着重介绍它的最后四行。XMLExists 函数指示 DB2 确定一个给定 XML 文档是否包含其中包含特定城市和州的客户地址。PASSING 子句指定可以在哪里找到 XML 文档:在 "contactinfo" 列中。CAST 函数被调用两次,以将输入参数的值(针对城市和州)强制转换适当的数据类型。

    该程序的输出类似于 清单 9 展示的输出,假设 Lisa Hansen 和 Amy 都居住在加利福尼亚州圣何塞。

    使用 XQuery 作为顶层语言

    尽管 DB2 完全支持 XQuery 作为顶层语言,但是最初的 XQuery 规范并不解析参数标志符。作为一个实际问题,这限制了 XQueries 在 Java 应用程序中的使用。前几节演示了如何在 SQL 中嵌入 XQueries(例如,使用 XMLQuery 和 XMLExists 函数),以合并参数标志符。本节介绍利用纯 XQuery 可以在 Java 应用程序中做什么。

    下面这个例子中包含的 XQuery 类似于 "Query DB2 XML Data with XQuery"(developerWorks,2006 年 4 月)中给出的。该 XQuery 确定哪些客户居住在加利福尼亚州圣何塞。对于每个这样的客户,它会构造一个包含 "emailList"(其中包含该客户的所有电子邮件地址)的 XML 片段。最后,它返回一个 emailLists 序列。

    清单 11. 利用 XQuery 检索 XML 片段

try{ // get a database connection Connection conn = Conn.getConn(); // define, prepare, and execute an XQuery (without SQL). // note that we must hard-code query predicate values. String query = "xquery for $y in db2-fn:xmlcolumn" + "('CLIENTS.CONTACTINFO')/Client " + "where $y/Address/city=\"San Jose\" and $y/Address/state=\"CA\" " + "return <emailList> { $y/email } </emailList>"; PreparedStatement selectStmt = conn.prepareStatement(query); ResultSet rs = selectStmt.executeQuery(); // iterate over all items in the sequence and print results. while(rs.next() ){ System.out.println(rs.getString(1)); } // release all resources . . . // catch and handle any exceptions . . . }

    该查询有两个方面值得注意。首先,查询字符串以关键词 "xquery" 打头。这指示 DB2 使用它的 XQuery 解析器来处理查询。每当使用 XQuery 作为最外层语言时,您都需要这样做。其次,查询以大写形式引用表和列的名称。XQuery 是一种大小写敏感的语言。因为当把该信息写入它的内部编目时,DB2 通常将表和列的名称转换成大写形式,所以 XQuery 必须匹配该信息。

    该程序的示例输出如 清单 12 所示。因为为每个符合条件的客户返回一个 "emailList" 项,快速扫视一下该输出,可以看到四个客户符合条件。第一个符合条件的记录包含一个电子邮件地址。第二个不包含(也许是因为客户不提供该信息);因此,它的 emailList 为空。第三个符合条件的记录指出该客户的记录中有两个电子邮件地址。第四个记录包含客户的一个电子邮件地址。

    清单 12. 前一个应用程序的示例输出  

<emailList><email>newemail@someplace.com</email></emailList> <emailList/> <emailList><email>beatlesfan36@hotmail.com</email> <email>lennonfan36@hotmail.com</email></emailList> <emailList><email>sailer555@yahoo.com</email></emailList>

    您也许感到好奇,为什么并不是每个符合条件的客户的姓名都包含在我们的结果中。答案很简单:XQuery 处理 XML 数据,而客户姓名存储在 SQL VARCHAR 列中。所以,如果您想要输出中包含符合条件的客户的姓名及其电子邮件地址,那么应该编写同时包含 SQL 和 XQuery 的查询。

0
相关文章