使用 SQLXML 数据类型

适用于数据库 XML 类型的 Java 数据类型

Deepak Vohra

2006 年 6 月 10 日发布

概述

J2EE 开发人员通常需要在关系数据库中存储 XML 文档以及从数据库中检索 XML 文档,以获得元素值和属性值。目前,只有特定于供应商的技术和数据类型可用于在关系数据库中存储 XML 文档。例如 IBM DB2 Universal Database™ (UDB) 提供了 DB2 XML Extender 和 XML 用户定义类型 (UDT) 来存储 XML 文档。用于 XML 类型列的标准数据类型和对应于 XML 类型列的 Java 数据类型将促进关系数据库中 XML 文档的存储和检索。SQL:2003 标准支持这样一种数据类型:新 XML 数据类型,以便在关系数据库中存储 XML 文档。借助 XML 数据类型,您可以在类似于其他数据类型的数据库表列中存储 XML 文档。DB2 Viper(即 DB2 UDB Version 9.1)支持 XML 数据类型。Java Database Connectivity (JDBC) 4.0 规范支持 SQL:2003 标准。

初步设置

在开始之前,确保拥有必要的组件。SQLXML 是一种 JDBC 4.0 数据类型。因为 SQLXML 数据类型是在 Sun 提供的 Java SE 6 Development Kit (JDK) 6.0 Beta 中实现的,所以您需要安装它。另一个要求是创建一个 SQLXML 类型对象,该对象是一个支持 XML 数据类型的关系数据库。DB2 Viper(即 DB2 UDB Version 9.1)支持 XML 数据类型。要运行本文中包含的示例应用程序 SQLXMLDB.java,需要安装 DB2 Viper 数据库,并创建示例 DB2 数据库实例 Sample。JDK 6.0 Beta、DB2 Viper 和 SQLXMLDB.java 可以分别从 参考资料 和 下载 中获得。

您还需要一个 JDBC 4.0 驱动程序,但 DB2 UDB 目前并没有提供 JDBC 4.0 驱动程序,要运行带有 DB2 JDBC 3.0 驱动程序的 SQLXMLDB.java 并确定 DB2 数据库是否支持 XML 数据类型,需要将 JAR 文件 C:/Program Files/IBM/SQLLIB/java/db2jcc.jar 和 C:/Program Files/IBM/SQLLIB/java/db2jcc_license_cu.jar 添加到 Classpath 中。当 JDBC 4.0 驱动程序变得可用时,就可以利用 SQLXML API 运行 SQLXMLDB.java 了。当 JDBC 4.0 驱动程序变得可用时,本文将被更新。

开始

SQLXML Java 数据类型允许您将 XML 类型数据库列映射到 Java 数据类型。在 JDBC 4.0 规范中,java.sql.Connection 接口可以创建一个最初没有任何数据的 SQLXML 对象,但您可以用 setString(String) 方法或 createXMLStreamWriter() 方法添加数据。SQLXML 对象可利用 getSQLXML(int columnIndex) 方法或 getSQLXML(String columnName) 方法从 ResultSet 或 CallableStatement 对象中获得。可以用 getString() 方法或 createXMLStreamReader() 方法检索 SQLXML 对象中的数据,还可以用 PreparedStatement 接口的 setSQLXML(int parameterIndex, SQLXML sqlXML) 方法在类似于其他任何数据类型的类型 XML 的数据库表列中存储 SQLXML 对象。

清单 1 显示了一个您可以创建的 XML 文档的例子,即 catalog.xml:

清单 1. 示例 XML 文档 catalog.xml

Managing XML data: Tag URIs

Elliotte Harold

Practical data binding: XPath as data binding tool, Part 2

Brett McLaughlin

选择数据库

需要一个关系数据库来支持 XML 数据类型存储 XML 文档,不是所有的数据库都支持 XML 数据类型。要确定数据库是否支持该数据库类型,需要从 Connection 对象中获得数据库元数据。例如,要测试 DB2 Viper 是否支持 XML 数据类型,需要加载并注册 com.ibm.db2.jcc.DB2Driver JDBC 驱动程序,即 DB2 JDBC Type 4 驱动程序:Class.forName("com.ibm.db2.jcc.DB2Driver");

为 DB2 UDB 数据库指定连接 URL。DB2 UDB Type 4 驱动程序的格式为 jdbc:db2://:/。在此连接 URL 中, 是 DB2 UDB 服务器名称, 是 DB2 数据库端口,而 是 DB2 数据库实例。DB2 UDB 数据库的连接 URL 是:String url = "jdbc:db2://localhost:50000/Sample";

利用 DriverManager 的静态方法 getConnection() 获得与数据库的 Connection:Connection connection = DriverManager.getConnection(url,

"username", "password");

接下来,从 Connection 对象获得数据库元数据:DatabaseMetaData metadata = connection.getMetaData();

然后,利用 getTypeInfo() 方法获得受数据库支持的数据类型:ResultSet rs = metadata.getTypeInfo();

在数据类型结果集上进行迭代并输出 TYPE_NAME 列:System.out.println("TYPE_NAME:"+rs.getString("TYPE_NAME"));

如果数据库支持 XML 数据类型,则 XML TYPE_NAME 获得输出。由于 DB2 Viper 数据库支持 XML 数据类型,所以运行 SQLXMLDB.java 应用程序所得到的输出包括 XML 数据类型,如下所示:TYPE_NAME: XML

创建 SQLXML 对象

这一节将讨论创建 SQLXML 对象的过程。首先,导入 java.sql package 和 javax.xml.stream 包。javax.xml.stream 包具有实例化 SQLXML 对象和获得 SQLXML 对象中的数据所需的 XMLStreamWriter 和 XMLStreamReader 接口。import java.sql.*;

import javax.xml.stream.*;

XML 文档在类型为 XML 的数据库表列中的 Java 表示是 SQLXML。要创建一个将存储在 XML 类型列中的 XML 文档,需要使用 createSQLXML() 方法从 Connection 对象创建一个 SQLXML 对象:SQLXML sqlXML = connection.createSQLXML();

用 createSQLXML() 方法创建的 SQLXML 对象不包含任何数据。下一节 将展示如何将数据添加到 SQLXML 对象中。

初始化 SQLXML 对象

您可以使用 XMLStreamWriter 对象创建一个 XML 文档。可以使用 createXMLStreamWriter() 方法从 SQLXML 对象中创建 XMLStreamWriter 对象:XMLStreamWriter xmlStreamWriter = sqlXML.createXMLStreamWriter();

如果调用 createXMLStreamWriter() 方法,而不是使用相同的 SQLXML 对象,则会抛出 SQLException,并且先前返回的 XMLStreamWriter 对象不受影响。

用 writeStartDocument(String encoding, String version) 方法添加 XML 文档的开始部分。writeStartDocument() 方法中指定的编码并没有设置 XML 文档输出的编码;指定的编码只设置 XML 声明中的编码。XMLStreamWriter 接口还包括 writeStartDocument() 方法和 writeStartDocument(String version) 方法,前者用于在没有指定编码和版本的情况下创建 XML 文档,后者用于在提供版本的情况下创建 XML 文档:xmlStreamWriter.writeStartDocument("UTF-8","1.0");

用 writeStartElement(String localName) 方法(如下面代码片段所示)添加根元素 catalog 的开始部分。使用 writeStartElement(String prefix, String localName, String namespaceURI) 方法根据名称空间和前缀创建一个元素。使用 writeEmptyElement(String localName) 方法可生成一个空元素:xmlStreamWriter.writeStartElement("catalog");

用 writeAttribute(String localName, String value) 方法添加 title 属性,如下面代码片段所示。同样,还可以添加 publisher 属性。如果属性有一个名称空间前缀,则使用方法 writeAttribute(String prefix, String namespaceURI, String localName, String value):xmlStreamWriter.writeAttribute("title", "XML Zone");

xmlStreamWriter.writeAttribute("publisher", "IBM developerWorks");

类似地,还可以添加 journal 元素及其属性 date:xmlStreamWriter.writeStartElement("journal");

xmlStreamWriter.writeAttribute("date", "Jan 2006");

添加一个 article 元素和一个 title 元素:xmlStreamWriter.writeStartElement("article");

xmlStreamWriter.writeStartElement("title");

用 writeCharacters(String text) 方法将文本添加到 title 元素中,如下面代码片段所示。此外,可以使用 writeCharacters(char[] text,int start,int len) 方法从 char[] 数组中添加文本。xmlStreamWriter.writeCharacters("Managing XML data: Tag URIs");

确保 start 元素有一个相应的 end 元素标记。使用 writeEndElement() 方法添加一个 end 元素:xmlStreamWriter.writeEndElement();

writeEndElement() 方法没有像 writeStartElement() 方法那样指定元素的本地名称。类似地,可以添加其他元素来创建 清单 1 中所示的 XML 文档。要完成 XML 文档,请调用 writeEndDocument() 方法。此外,请关闭 XMLStreamWriter 对象:xmlStreamWriter.writeEndDocument();

xmlStreamWriter.close();

您还可以使用 SQLXML 接口的 setString(String) 方法将 XML 文档从 XML 字符串添加到 SQLXML 对象中,如 清单 2 所示。如果在前面已初始化的 SQLXML 对象上调用 setString(String) 方法,则会抛出 SQLException。

清单 2. 将 XML 文档添加到 SQLXML 对象中sqlXML.setString("

Managing XML data: Tag URIs

Elliotte Harold

Practical data binding: XPath as data binding tool, Part 2

Brett McLaughlin

");

下一节 解释如何将创建的 SQLXML 对象存储到数据库中。

存储 SQLXML 对象

SQLXML Java 数据类型存储在 XML 文档中,就像其他任何 Java 数据类型那样。首先,用 XML 类型列创建一个数据库表。可以借助 SQL 命令行工具或 JDBC API,用 XML 类型列创建数据库表。要用 JDBC 创建数据库表,需要从 Connection 对象中获得一个 Statement 对象:Statement stmt = connection.createStatement();

用 XML 类型列创建一个数据库表,比如 Catalog:stmt.executeUpdate("CREATE Table Catalog(CatalogId INTEGER, Catalog XML)");

将 前一节 中创建的 SQLXML 对象添加到数据库中。创建一个 PreparedStatement 对象,以便将值添加到数据库表 Catalog 中。PreparedStatement 由 INSERT SQL 语句和用来添加到数据库的那些值的参数标志符组成:PreparedStatement statement =

connection.prepareStatement("INSERT INTO CATALOG(catalogId, catalog) VALUES(?,?)");

用 setInt(int parameterIndex, int value) 方法设置 int 值,用 PreparedStatement 接口的 setSQLXML(int parameterIndex, SQLXML value) 方法设置 SQLXML 值,如下所示。如果没有在调用 setSQLXML() 方法前关闭 XMLStreamWriter 对象,则会抛出 SQLException。statement.setInt(1, 1);

statement.setSQLXML(2, sqlXML);

用 executeUpdate() 方法更新数据库:statement.executeUpdate();

SQLXML 对象至少在创建 SQLXML 对象期间是有效的。如果不使用某个 SQLXML 对象,则可以使用 free() 方法释放这个 SQLXML 对象资源:sqlXML.free();

更新 SQLXML 对象

JDK 6.0 Beta 还在 ResultSet 接口中提供了一些 updater 方法来更新 SQLXML 值。updater 方法 updateSQLXML(int columnIndex, SQLXML sqlXML) 和 updateSQLXML(String columnName, SQLXML sqlXML) 可修改当前行中的 SQLXML 值或 ResultSet 对象的插入行。例如,要在 ResultSet 对象中添加新行,需要获得一个不可更新的 ResultSet 类型的 Statement 对象:Statement stmt = connection.createStatement(

ResultSet.TYPE_SCROLL_INSENSITIVE,

ResultSet.CONCUR_UPDATABLE);

从数据库表 Catalog 获得一个 ResultSet,该表有一个 XML 类型的列。可以移动 ResultSet 游标来插入一个行。还可以使用 updateSQLXML() 方法添加 SQLXML 列值。updateSQLXML() 方法不更新数据库。要更新数据库,需要调用 insertRow() 方法:ResultSet rs = stmt.executeQuery("SELECT * from Catalog");

rs.moveToInsertRow();

rs.updateSQLXML(2, xmlObject);

rs.insertRow();

此外,要在可滚动的 ResultSet 中从当前行更新 ResultSet,需要使用 absolute(int) 或 relative(int) 方法移动到 ResultSet 行。可以使用 updater 方法之一修改 SQLXML 值。使用 updateRow() 方法更新数据库:rs.absolute(5);

updateSQLXML("catalog", xmlObject)

rs.updateRow();

如果没有在调用 updater 方法之前关闭 XMLStreamWriter 对象,则会抛出 SQLException。

从 ResultSet 对象检索 SQLXML 对象

以 SQLXML 数据类型的形式检索 XML 数据库类型列值。为 SELECT SQL 查询创建一条 PreparedStatement,以便从数据库表 Catalog 中获得 ResultSet,如下面代码片段所示。SQL 语句有一个用于 CatalogId 值的参数标志符。PreparedStatement stmt =

connection.prepareStatement("SELECT * FROM CATALOG WHERE CatalogId=?");

指定将从中检索 XML 文档的 CatalogId 值:stmt.setInt(1, 1);

用 executeQuery() 方法获得一个结果集:ResultSet rs = stmt.executeQuery();

使用 ResultSet 接口的方法 getSQLXML(int columnIndex) 或 getSQLXML(String columnName) 获得用于 XML 类型 Catalog 列的 SQLXML 对象:SQLXML sqlXML = rs.getSQLXML("Catalog");

要在 SQLXML 对象中输出 XML 文档,可能需要使用 SQLXML 接口的 getString() 方法:System.out.println(sqlXML.getString());

访问 SQLXML 对象

使用 XMLStreamReader 接口读取具有事件迭代器的 SQLXML 对象中的 XML 文档。从将被导航的 SQLXML 对象中创建一个 XMLStreamReader 对象:XMLStreamReader xmlStreamReader = sqlXML.createXMLStreamReader();

下一个解析事件是用 next() 方法获得的:while(xmlStreamReader.hasNext()){

int parseEvent = xmlStreamReader.next();

}

next() 方法返回一个对应于 XMLStreamConstants 常量的 int 值。表 1 列出了 next() 方法的返回值。

表 1. 方法 next() 的返回值解析事件描述ATTRIBUTE指定一个属性

CDATACData 部分

CHARACTERS文本

NOTATION_DECLARATION指定一个符号声明

COMMENTXML 文档注释

PROCESSING_INSTRUCTION指定一个处理指令

START_DOCUMENT指定文档的开始处

START_ELEMENT指定元素的开始处

END_ELEMENT指定元素的结尾处

ENTITY_DECLARATION指定一个实体声明

ENTITY_REFERENCE指定一个实体引用

NAMESPACE指定一个名称空间声明

SPACE指定一个可忽略的空白

END_DOCUMENT指定文档的结尾处

DTD指定一个 DTD

如果返回值是 START_ELEMENT,则解析事件指示某一元素已经被解析。可以使用方法 getLocalName()、getPrefix()、getNamespaceURI() 获得本地名称、前缀和名称空间元素:if(parseEvent==XMLStreamConstants.START_ELEMENT){

System.out.println("Element Local Name: "+xmlStreamReader.getLocalName());

System.out.println("Element Prefix: "+xmlStreamReader.getPrefix());

System.out.println("Element Namespace:"+xmlStreamReader.getNamespaceURI());

}

可以使用 getAttributeCount() 方法获得元素中的属性总数。还可以在属性上进行迭代,使用 getAttributeLocalName() 方法获得属性本地名称,使用 getAttributeValue() 方法获得属性值,使用 getAttributePrefix() 方法获得属性前缀,以及使用 getAttributeNamespace() 方法获得属性名称空间:for(int i=0; i

System.out.println("Attribute Prefix:"+xmlStreamReader.getAttributePrefix(i));

System.out.println("Attribute Namespace:"+xmlStreamReader.getAttributeNamespace(i));

System.out.println("Attribute Local Name:"+xmlStreamReader.getAttributeLocalName(i));

System.out.println("Attribute Value:"+xmlStreamReader.getAttributeValue(i));

}

如果解析事件的类型为 CHARACTERS,可使用 getText() 方法获得解析事件的文本:if(parseEvent==XMLStreamConstants.CHARACTERS){

System.out.println("CHARACTERS text: "+xmlStreamReader.getText());

}

结束语

SQLXML 数据类型为数据库类型 XML 提供了数据库到 Java 的映射工具。您可以对任何支持 XML 数据类型并提供 JDBC 4.0 驱动程序的数据库使用 SQLXML 数据类型。特定于供应商的 XML-to-SQL API 对 SQLXML 不是必需的。SQLXML API 将包含在 JDK 6.0 中。DB2 Viper 支持 XML 数据类型。

下载资源

相关主题您可以参阅本文在 developerWorks 全球站点上的 英文原文。

DB2 UDB Version 9:下载和测试促使 DB2 Viper 更多地了解这种既支持关系存储又支持 XML 存储的混合数据服务器。

JDK 6.0 Beta:获得实现 SQLXML 的 JDK。

专家访谈: Susan Malaika 讨论 DB2 中的 XML 功能(developerWorks,2002 年 12 月):在这一期 专家访谈 中,学习关于 DB2 数据库中的 XML 支持的知识。

DB2 UDB 和 DB2 XML Extender 中 SQL/XML 函数的介绍(developerWorks,2003 年 11 月):阅读这篇关于 DB2 UDB 和 DB2 XML Extender 中的 SQL/XML 功能的介绍。

SQL/XML 发布函数简介(developerWorks,2005 年 11 月):了解 SQL/XML 发布功能。

用 SQL 查询 DB2 XML 数据(developerWorks,2006 年 3 月):了解如何使用 SQL 和 SQL/XML 查询存储在 XML 列中的数据。

developerWorks XML 专区:在这里可以找到更多的 XML 参考资料,其中包括一些文章、教程、提示和标准。

mysql中xml类型_使用 SQLXML 数据类型相关推荐

  1. c#和mysql之间的类型_【SqlServer数据类型、C#数据类型、SqlDbType】对应关系及转换...

    // sql server数据类型(如:varchar) // 转换为SqlDbType类型 public static SqlDbType SqlTypeString2SqlType(string ...

  2. mysql 存储xml类型_(MariaDB)MySQL数据类型详解和存储机制

    1.1 数据类型概览 数据类型算是一种字段约束,它限制每个字段能存储什么样的数据.能存储多少数据.能存储的格式等.MySQL/MariaDB大致有5类数据类型,分别是:整形.浮点型.字符串类型.日期时 ...

  3. python mysql写入速度加快_解决python写入mysql中datetime类型遇到的问题

    解决python写入mysql中datetime类型遇到的问题 发布时间:2020-08-31 16:46:47 来源:脚本之家 阅读:89 作者:WilliamDescant 刚开始使用python ...

  4. python mysql驱动写入datetime类型的数据_解决python写入mysql中datetime类型遇到的问题...

    刚开始使用python,还不太熟练,遇到一个datetime数据类型的问题: 在mysql数据库中,有一个datetime类型的字段用于存储记录的日期时间值.python程序中有对应的一个dateti ...

  5. mysql数据类型double,double在数据库怎么定义 mysql中double类型在sql中用什么类型

    sql定义一个double变量怎么定义? 局部变量 声明:DECLARE @local_variable data_type @local_variable 是变量的名称.变量名必须以 at 符 (@ ...

  6. MySql中json类型的使用___mybatis存取mysql中的json

    MySql中json类型的使用 MySQL从5.7.8起开始支持JSON字段,这极大的丰富了MySQL的数据类型.也方便了广大开发人员.但MySQL并没有提供对JSON对象中的字段进行索引的功能,至少 ...

  7. MYSQL中 ENUM 类型

    MYSQL中 ENUM 类型的详细解释 ENUM类型 ENUM 是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举. 在下列某些情况下,值也可以是空串(&quo ...

  8. MYSQL中TIMESTAMP类型的默认值

    MYSQL中TIMESTAMP类型的默认值    MYSQL中TIMESTAMP类型可以设定默认值,就像其他类型一样. 1.自动UPDATE 和INSERT 到当前的时间: 表: ---------- ...

  9. mysql java 获取周_Java中获取Mysql中datetime类型的数据

    由于Java中的日期类型只有Date类型,而Mysql中即有date型,又有datetime型,当我们想要在java中获取Mysql中datetime类型的数据或向Mysql数据库中插入datetim ...

最新文章

  1. POJ2195费用流+BFS建图
  2. java 第三方代码_Java:如何使用第三方库?
  3. 学计算机cpu重要还是显卡重要,玩游戏的过程中究竟是显卡重要还是CPU重要?
  4. 一次完整的http的请求过程与https的实现
  5. diskgenius 接触“只读“失败_相亲总是失败,这三个步骤你都做了吗?
  6. 使用jQuery Mobile移动开发框架将博客网站快速转化为Mobile网站
  7. 阿里云数据库产品专家胡航丽:数据库自动驾驶平台DAS重磅助力数据库领域智能未来...
  8. UI设计师必备的网站推荐
  9. 滴滴出行回应导航崩了;微信支付正式上线「向手机号转账」功能;Guns 6.0 发布 | 极客头条...
  10. python如何学的扎实_如何系统的学习python?
  11. dds通信中间件_车内的中间件协议:是面向服务,还是以数据为中心,或是RESTful?...
  12. 字符串(strlen)
  13. Atitit 医学之道 attilax总结
  14. linux在线汇编编译器,Linux 汇编 Hello World
  15. 微型计算机怎么插入光盘,解决Win 7读光盘“请将磁盘插入DVD驱动器”故障
  16. Mac 上的 iOS App 可用性(IOS APP availability on Mac)
  17. Linux Shell字符串变量头尾去除空格
  18. 经典Vue面试题一起学起来
  19. Docker常用容器命令
  20. 蓝桥杯-2020-Java-B组-装饰珠-动态规划

热门文章

  1. Centos7安装tengine-2.3.2版本
  2. spirng 如何把404转到特定的页面展示
  3. Qt 断言的使用 Q_ASSERT
  4. “优秀IT工程师”是什么样的?
  5. 从补码的来源剖析到为啥补码=原码按位取反+1
  6. 9篇小白都能懂系列博客学完MySQL基础
  7. c++ map用法_Pandas数据处理三板斧——map、apply、applymap详解
  8. 树莓派分辨率调整(含官方默认和kali系统)
  9. 堆栈的生长方向和空栈满栈的区别
  10. 百度智能云拿下MTCS最高安全评级,企业出海再添安全通道