使用 SQLXML 对象

Connectioninterface支持使用createSQLXML方法创建SQLXML个对象。创建的对象不包含任何数据。可以通过在SQLXMLinterface上调用setStringsetBinaryStreamsetCharacterStreamsetResult方法将数据添加到对象。

涵盖以下主题:

创建 SQLXML 对象

在以下摘录中,方法Connection.createSQLXML用于创建一个空的SQLXML对象。 SQLXML.setString方法用于将数据写入创建的SQLXML对象。

Connection con = DriverManager.getConnection(url, props);
SQLXML xmlVal = con.createSQLXML();
xmlVal.setString(val);

检索 ResultSet 中的 SQLXML 值

SQLXML数据类型的处理方式与更原始的内置类型类似。可以通过在ResultSetCallableStatementinterface中调用getSQLXML方法来检索SQLXML值。

例如,以下摘录从ResultSet rs 的第一列中检索SQLXML值:

SQLXML xmlVar = rs.getSQLXML(1);

SQLXML对象至少在创建它们的事务期间保持有效,除非调用了它们的free方法。

访问 SQLXML 对象数据

SQLXMLinterface提供getStringgetBinaryStreamgetCharacterStreamgetSource方法以访问其内部内容。以下摘录使用getString方法检索SQLXML对象的内容:

SQLXML xmlVal= rs.getSQLXML(1);
String val = xmlVal.getString();

getBinaryStreamgetCharacterStream方法可用于获取可以直接传递到 XML 解析器的InputStreamReader对象。以下摘录从SQLXML对象获得InputStream对象,然后使用 DOM(文档对象模型)解析器处理流:

SQLXML sqlxml = rs.getSQLXML(column);
InputStream binaryStream = sqlxml.getBinaryStream();
DocumentBuilder parser = 
    DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document result = parser.parse(binaryStream);

getSource方法返回javax.xml.transform.Source对象。源用作 XML 解析器和 XSLT 转换器的 Importing。

以下摘录使用通过调用getSource方法返回的SAXSource对象从SQLXML对象检索并解析数据:

SQLXML xmlVal= rs.getSQLXML(1);
SAXSource saxSource = sqlxml.getSource(SAXSource.class);
XMLReader xmlReader = saxSource.getXMLReader();
xmlReader.setContentHandler(myHandler);
xmlReader.parse(saxSource.getInputSource());

存储 SQLXML 对象

就像其他数据类型一样,SQLXML对象可以作为 Importing 参数传递给PreparedStatement对象。方法setSQLXMLSQLXML对象设置指定的PreparedStatement参数。

在以下摘录中,authorDatajava.sql.SQLXMLinterface的实例,该interface的数据先前已初始化。

PreparedStatement pstmt = conn.prepareStatement("INSERT INTO bio " +
                              "(xmlData, authId) VALUES (?, ?)");
pstmt.setSQLXML(1, authorData);
pstmt.setInt(2, authorId);

updateSQLXML方法可用于更新可更新结果集中的列值。

如果在调用setSQLXMLupdateSQLXML之前尚未关闭SQLXML对象的java.xml.transform.ResultWriterOutputStream对象,则将引发SQLException

初始化 SQLXML 对象

SQLXMLinterface提供方法setStringsetBinaryStreamsetCharacterStreamsetResult来初始化已通过调用Connection.createSQLXML方法创建的SQLXML对象的内容。

以下摘录使用方法setResult返回SAXResult对象,以填充新创建的SQLXML对象:

SQLXML sqlxml = con.createSQLXML();
SAXResult saxResult = sqlxml.setResult(SAXResult.class);
ContentHandler contentHandler = saxResult.getXMLReader().getContentHandler();
contentHandler.startDocument();
    
// set the XML elements and
// attributes into the result
contentHandler.endDocument();

以下摘录使用setCharacterStream方法来获取java.io.Writer对象,以便初始化SQLXML对象:

SQLXML sqlxml = con.createSQLXML();
Writer out= sqlxml.setCharacterStream();
BufferedReader in = new BufferedReader(new FileReader("xml/foo.xml"));
String line = null;
while((line = in.readLine() != null) {
    out.write(line);
}

同样,SQLXML setString方法可用于初始化SQLXML对象。

如果try在先前已初始化的SQLXML对象上调用setStringsetBinaryStreamsetCharacterStreamsetResult方法,则将抛出SQLException。如果对于同一个SQLXML对象发生了对方法setBinaryStreamsetCharacterStreamsetResult的多次调用,则抛出SQLException且先前返回的javax.xml.transform.ResultWriterOutputStream对象不受影响。

释放 SQLXML 资源

SQLXML对象至少在创建它们的 Transaction 期间保持有效。在 Long 期运行的事务中,这可能导致应用程序资源不足。应用程序可以通过调用free方法来释放SQLXML资源。

在以下摘录中,调用method SQLXML.free以释放为先前创建的SQLXML对象保留的资源。

SQLXML xmlVar = con.createSQLXML();
xmlVar.setString(val);
xmlVar.free();

Sample Code

MySQL 和 Java DB 及其各自的 JDBC 驱动程序不完全支持本节中介绍的SQLXML JDBC 数据类型。但是,samplesRSSFeedsTable演示了如何使用 MySQL 和 Java DB 处理 XML 数据。

The Coffee Break 的所有者关注着来自各种网站的一些 RSS 提要,这些提要涵盖了餐饮业的新闻。 RSS(true 简单的联合组织或富网站摘要)提要是一个 XML 文档,其中包含一系列文章和相关的元数据,例如每篇文章的发布日期和作者。所有者希望将这些 RSS 提要存储到数据库表中,其中包括 The Coffee Break 博客中的 RSS 提要。

文件rss-the-coffee-break-blog.xml是 The Coffee Break 博客的 RSS 提要示例。

在 MySQL 中使用 XML 数据

samplesRSSFeedsTable将 RSS 提要存储在表RSS_FEEDS中,该表是通过以下命令创建的:

create table RSS_FEEDS
    (RSS_NAME varchar(32) NOT NULL,
    RSS_FEED_XML longtext NOT NULL,
    PRIMARY KEY (RSS_NAME));

MySQL 不支持 XML 数据类型。而是,此示例将 XML 数据存储在LONGTEXT类型的列中,该列是CLOB SQL 数据类型。 MySQL 有四种CLOB数据类型。 LONGTEXT数据类型在这四个字符中包含最多的字符。

方法RSSFeedsTable.addRSSFeed将 RSS 提要添加到RSS_FEEDS表中。此方法的第一条语句将 RSS feed(在此示例中由 XML 文件表示)转换为org.w3c.dom.Document类型的对象,该对象表示 DOM(文档对象模型)文档。此类以及包javax.xml中包含的类和interface,包含使您能够处理 XML 数据内容的方法。例如,以下语句使用 XPath 表达式从Document对象检索 RSS feed 的标题:

Node titleElement =
    (Node)xPath.evaluate("/rss/channel/title[1]",
        doc, XPathConstants.NODE);

XPath 表达式/rss/channel/title[1]检索第一个<title>元素的内容。对于文件rss-the-coffee-break-blog.xml,这是字符串The Coffee Break Blog

以下语句将 RSS 提要添加到表RSS_FEEDS

// For databases that support the SQLXML
// data type, this creates a
// SQLXML object from
// org.w3c.dom.Document.

System.out.println("Adding XML file " + fileName);
String insertRowQuery =
    "insert into RSS_FEEDS " +
    "(RSS_NAME, RSS_FEED_XML) values " +
    "(?, ?)";
insertRow = con.prepareStatement(insertRowQuery);
insertRow.setString(1, titleString);

System.out.println("Creating SQLXML object with MySQL");
rssData = con.createSQLXML();
System.out.println("Creating DOMResult object");
DOMResult dom = (DOMResult)rssData.setResult(DOMResult.class);
dom.setNode(doc);

insertRow.setSQLXML(2, rssData);
System.out.println("Running executeUpdate()");
insertRow.executeUpdate();

RSSFeedsTable.viewTable方法检索RSS_FEEDS的内容。对于每一行,该方法创建一个名为doc的类型org.w3c.dom.Document的对象,该对象将 XML 内容存储在RSS_FEED_XML列中。该方法检索 XML 内容并将其存储在名为rssFeedXMLSQLXML类型的对象中。 rssFeedXML的内容被解析并存储在doc对象中。

在 Java DB 中使用 XML 数据

注意 :有关在 Java DB 中使用 XML 数据的更多信息,请参见Java DB 开发人员指南中的“ XML 数据类型和运算符”部分。

samplesRSSFeedsTable将 RSS 提要存储在表RSS_FEEDS中,该表是通过以下命令创建的:

create table RSS_FEEDS
    (RSS_NAME varchar(32) NOT NULL,
    RSS_FEED_XML xml NOT NULL,
    PRIMARY KEY (RSS_NAME));

Java DB 支持 XML 数据类型,但不支持SQLXML JDBC 数据类型。因此,您必须将任何 XML 数据转换为字符格式,然后使用 Java DB 运算符XMLPARSE将其转换为 XML 数据类型。

RSSFeedsTable.addRSSFeed方法将 RSS 提要添加到RSS_FEEDS表中。此方法的第一条语句将 RSS feed(在此示例中由 XML 文件表示)转换为org.w3c.dom.Document类型的对象。 在 MySQL 中使用 XML 数据部分对此进行了描述。

RSSFeedsTable.addRSSFeed方法使用JDBCTutorialUtilities.convertDocumentToString方法将 RSS feed 转换为String对象。

Java DB 具有一个名为XMLPARSE的运算符,该运算符将字符串 表示形式解析为 Java DB XML 值,以下摘录演示了这一点:

String insertRowQuery =
    "insert into RSS_FEEDS " +
    "(RSS_NAME, RSS_FEED_XML) values " +
    "(?, xmlparse(document cast " +
    "(? as clob) preserve whitespace))";

XMLPARSE运算符要求您将 XML 文档的字符表示形式转换为 Java DB 可以识别的字符串 数据类型。在此示例中,它将其转换为CLOB数据类型。有关 Apache Xalan 和 Java DB 要求的更多信息,请参见Getting Started和 Java DB 文档。

方法RSSFeedsTable.viewTable检索RSS_FEEDS的内容。由于 Java DB 不支持 JDBC 数据类型SQLXML,因此必须将 XML 内容作为字符串 检索。 Java DB 有一个名为XMLSERIALIZE的运算符,该运算符将 XML 类型转换为字符类型:

String query =
    "select RSS_NAME, " +
    "xmlserialize " +
    "(RSS_FEED_XML as clob) " +
    "from RSS_FEEDS";

XMLPARSE运算符一样,XMLSERIALIZE运算符要求在您的 JavaClasspath 中列出 Apache Xalan。