文档

Java™ 教程
隐藏目录
使用SQLXML对象
路径: JDBC数据库访问
课程: JDBC基础知识

使用SQLXML对象

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

以下主题包括:

创建SQLXML对象

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

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

从结果集中检索SQLXML值

SQLXML数据类型与更基本的内置类型类似处理。可以通过在ResultSetCallableStatement接口中调用getSQLXML方法来检索SQLXML值。

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

SQLXML xmlVar = rs.getSQLXML(1);

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

访问SQLXML对象数据

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

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

可以使用getBinaryStreamgetCharacterStream方法获取InputStreamReader对象,可以直接传递给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 对象

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

在以下代码片段中,authorDatajava.sql.SQLXML接口的一个实例,其数据先前已初始化:

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

可以使用updateSQLXML方法在可更新的结果集中更新列值。

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

初始化 SQLXML 对象

SQLXML接口提供了setStringsetBinaryStreamsetCharacterStreamsetResult方法,用于初始化通过调用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);
}

类似地,可以使用 SQLXMLsetString 方法来初始化一个 SQLXML 对象。

如果尝试在已经初始化过的 SQLXML 对象上调用 setStringsetBinaryStreamsetCharacterStreamsetResult 方法,将会抛出一个 SQLException 异常。如果对同一个 SQLXML 对象多次调用 setBinaryStreamsetCharacterStreamsetResult 方法,将会抛出一个 SQLException 异常,并且之前返回的 javax.xml.transform.ResultWriterOutputStream 对象不受影响。

释放 SQLXML 资源

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 订阅源。

在MySQL中使用XML数据

示例的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的内容。对于每一行,该方法创建一个名为docorg.w3c.dom.Document类型的对象,用于存储列RSS_FEED_XML中的XML内容。该方法检索XML内容并将其存储在名为rssFeedXMLSQLXML类型的对象中。将rssFeedXML的内容解析并存储在doc对象中。

在Java DB中使用XML数据

注意:请参阅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。


上一页: 使用大对象
下一页: 使用数组对象