使用 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 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
对象。
如果尝试在先前已初始化的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。