这些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。