使用 SQLXML 对象
原文: https://docs.oracle.com/javase/tutorial/jdbc/basics/sqlxml.html
Connection接口支持使用createSQLXML方法创建SQLXML对象。创建的对象不包含任何数据。可以通过调用SQLXML接口上的setString,setBinaryStream,setCharacterStream或setResult方法将数据添加到对象中。
涵盖以下主题:
在以下摘录中,方法Connection.createSQLXML用于创建空SQLXML对象。 SQLXML.setString方法用于将数据写入已创建的SQLXML对象。
Connection con = DriverManager.getConnection(url, props);SQLXML xmlVal = con.createSQLXML();xmlVal.setString(val);
SQLXML数据类型的处理方式与更原始的内置类型相似。通过调用ResultSet或CallableStatement接口中的getSQLXML方法可以检索SQLXML值。
例如,以下摘录从ResultSet rs 的第一列检索SQLXML值:
SQLXML xmlVar = rs.getSQLXML(1);
SQLXML对象至少在创建它们的事务持续时间内保持有效,除非调用它们的free方法。
SQLXML接口提供getString,getBinaryStream,getCharacterStream和getSource方法来访问其内部内容。以下摘录使用getString方法检索SQLXML对象的内容:
SQLXML xmlVal= rs.getSQLXML(1);String val = xmlVal.getString();
getBinaryStream或getCharacterStream方法可用于获取可直接传递给 XML 解析器的InputStream或Reader对象。以下摘录从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 转换器的输入。
以下摘录使用通过调用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对象可以作为输入参数传递给PreparedStatement对象。方法setSQLXML使用SQLXML对象设置指定的PreparedStatement参数。
在下面的摘录中,authorData是java.sql.SQLXML接口的一个实例,其数据先前已初始化。
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO bio " +"(xmlData, authId) VALUES (?, ?)");pstmt.setSQLXML(1, authorData);pstmt.setInt(2, authorId);
updateSQLXML方法可用于更新可更新结果集中的列值。
如果SQLXML对象的java.xml.transform.Result,Writer或OutputStream对象在调用setSQLXML或updateSQLXML之前尚未关闭,则会抛出SQLException。
SQLXML接口提供方法setString,setBinaryStream,setCharacterStream或setResult来初始化通过调用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 resultcontentHandler.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对象。
如果尝试在先前已初始化的SQLXML对象上调用setString,setBinaryStream,setCharacterStream和setResult方法,则将抛出SQLException。如果对同一SQLXML对象发生多次调用方法setBinaryStream,setCharacterStream和setResult,则抛出SQLException并返回先前javax.xml.transform.Result,Writer或OutputStream ]对象不受影响。
SQLXML对象至少在创建它们的事务期间保持有效。这可能导致应用程序在长时间运行的事务期间耗尽资源。应用程序可以通过调用free方法释放SQLXML资源。
在下面的摘录中,调用method SQLXML.free以释放为先前创建的SQLXML对象保留的资源。
SQLXML xmlVar = con.createSQLXML();xmlVar.setString(val);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中,该表使用以下命令创建:
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]($docs-gettingstarted.html)将 RSS 提要添加到RSS_FEEDS表。此方法的第一个语句将 RSS 提要(由此示例中的 XML 文件表示)转换为org.w3c.dom.Document类型的对象,该对象表示 DOM(文档对象模型)文档。此类以及包javax.xml中包含的类和接口包含使您能够操作 XML 数据内容的方法。例如,以下语句使用 XPath 表达式从Document对象检索 RSS 提要的标题:
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]($docs-gettingstarted.html)方法检索RSS_FEEDS的内容。对于每一行,该方法创建一个名为doc的org.w3c.dom.Document类型的对象,在该对象中将 XML 内容存储在RSS_FEED_XML列中。该方法检索 XML 内容并将其存储在名为rssFeedXML的SQLXML类型的对象中。 rssFeedXML的内容被解析并存储在doc对象中。
注:有关在 Java DB 中使用 XML 数据的更多信息,请参阅 Java DB 开发人员指南 中的“XML 数据类型和运算符”部分。
样例RSSFeedsTable将 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]($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 值,由以下摘录演示:
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 要求的更多信息,请参见入门和 Java DB 文档。
方法[RSSFeedsTable.viewTable]($docs-gettingstarted.html)检索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运算符要求在您的 Java 类路径中列出 Apache Xalan。
