使用 SQLXML 对象

原文: https://docs.oracle.com/javase/tutorial/jdbc/basics/sqlxml.html

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

涵盖以下主题:

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

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

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

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

  1. SQLXML xmlVar = rs.getSQLXML(1);

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

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

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

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

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

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

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

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

与其他数据类型一样,SQLXML对象可以作为输入参数传递给PreparedStatement对象。方法setSQLXML使用SQLXML对象设置指定的PreparedStatement参数。

在下面的摘录中,authorDatajava.sql.SQLXML接口的一个实例,其数据先前已初始化。

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

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

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

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

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

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

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

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

类似地,SQLXML setString方法可用于初始化SQLXML对象。

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

SQLXML对象至少在创建它们的事务期间保持有效。这可能导致应用程序在长时间运行的事务期间耗尽资源。应用程序可以通过调用free方法释放SQLXML资源。

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

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

MySQL 和 Java DB 及其各自的 JDBC 驱动程序不完全支持SQLXML JDBC 数据类型,如本节所述。但是,样例[RSSFeedsTable]($docs-gettingstarted.html)演示了如何使用 MySQL 和 Java DB 处理 XML 数据。

The Coffee Break 的所有者关注来自各种网站的多个 RSS 源,其中包括餐馆和饮料行业的新闻。 RSS(Really Simple Syndication 或 Rich Site Summary)源是一个 XML 文档,其中包含一系列文章和相关元数据,例如每篇文章的发布日期和作者。所有者希望将这些 RSS 提要存储到数据库表中,包括来自 The Coffee Break 博客的 RSS 提要。

文件[rss-the-coffee-break-blog.xml]($docs-gettingstarted.html)是来自 The Coffee Break 博客的示例 RSS 源。

样例RSSFeedsTable将 RSS 源存储在表RSS_FEEDS中,该表使用以下命令创建:

  1. create table RSS_FEEDS
  2. (RSS_NAME varchar(32) NOT NULL,
  3. RSS_FEED_XML longtext NOT NULL,
  4. PRIMARY KEY (RSS_NAME));

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

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

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

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

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

  1. // For databases that support the SQLXML
  2. // data type, this creates a
  3. // SQLXML object from
  4. // org.w3c.dom.Document.
  5. System.out.println("Adding XML file " + fileName);
  6. String insertRowQuery =
  7. "insert into RSS_FEEDS " +
  8. "(RSS_NAME, RSS_FEED_XML) values " +
  9. "(?, ?)";
  10. insertRow = con.prepareStatement(insertRowQuery);
  11. insertRow.setString(1, titleString);
  12. System.out.println("Creating SQLXML object with MySQL");
  13. rssData = con.createSQLXML();
  14. System.out.println("Creating DOMResult object");
  15. DOMResult dom = (DOMResult)rssData.setResult(DOMResult.class);
  16. dom.setNode(doc);
  17. insertRow.setSQLXML(2, rssData);
  18. System.out.println("Running executeUpdate()");
  19. insertRow.executeUpdate();

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

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

样例RSSFeedsTable将 RSS 源存储在表RSS_FEEDS中,该表使用以下命令创建:

  1. create table RSS_FEEDS
  2. (RSS_NAME varchar(32) NOT NULL,
  3. RSS_FEED_XML xml NOT NULL,
  4. PRIMARY KEY (RSS_NAME));

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

[RSSFeedsTable.addRSSFeed]($docs-gettingstarted.html)方法将 RSS 提要添加到RSS_FEEDS表。此方法的第一个语句将 RSS 提要(由此示例中的 XML 文件表示)转换为org.w3c.dom.Document类型的对象。这在使用 MySQL 中的 XML 数据一节中描述。

[RSSFeedsTable.addRSSFeed]($docs-gettingstarted.html)方法使用方法[JDBCTutorialUtilities.convertDocumentToString]($docs-gettingstarted.html)将 RSS 提要转换为String对象。

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

  1. String insertRowQuery =
  2. "insert into RSS_FEEDS " +
  3. "(RSS_NAME, RSS_FEED_XML) values " +
  4. "(?, xmlparse(document cast " +
  5. "(? as clob) preserve whitespace))";

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

方法[RSSFeedsTable.viewTable]($docs-gettingstarted.html)检索RSS_FEEDS的内容。由于 Java DB 不支持 JDBC 数据类型SQLXML,因此必须将 XML 内容检索为字符串。 Java DB 有一个名为XMLSERIALIZE的运算符,它将 XML 类型转换为字符类型:

  1. String query =
  2. "select RSS_NAME, " +
  3. "xmlserialize " +
  4. "(RSS_FEED_XML as clob) " +
  5. "from RSS_FEEDS";

XMLPARSE运算符一样,XMLSERIALIZE运算符要求在您的 Java 类路径中列出 Apache Xalan。