这些Java教程是为JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并且可能使用已不再可用的技术。
请参阅Java语言更改了解Java SE 9及后续版本中更新的语言特性的摘要。
请参阅JDK发行说明了解有关所有JDK版本的新功能、增强功能以及已删除或弃用选项的信息。
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方法获取InputStream或Reader对象,可以直接传递给XML解析器。以下摘录从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方法在可更新的结果集中更新列值。
如果在调用setSQLXML或updateSQLXML之前,SQLXML对象的java.xml.transform.Result、Writer或OutputStream对象未关闭,则会抛出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();
// 设置 XML 元素和属性到结果中
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.java 展示了如何处理 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 是 The Coffee Break 博客的一个示例 RSS 订阅源。文件 rss-coffee-industry-news.xml 是(虚构的)Coffee Industry News 的一个示例 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将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检索RSS_FEEDS的内容。对于每一行,该方法创建一个名为doc的org.w3c.dom.Document类型的对象,用于存储列RSS_FEED_XML中的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方法将RSS订阅源添加到RSS_FEEDS表中。该方法的第一条语句将RSS订阅源(在本示例中表示为XML文件)转换为org.w3c.dom.Document类型的对象。这在在MySQL中使用XML数据一节中有描述。
RSSFeedsTable.addRSSFeed方法使用方法JDBCTutorialUtilities.convertDocumentToString将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方法检索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。