首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JDBC 4.0 操作數據庫 XML 類型字段:存儲與讀取 java.sql.SQLXML 完整指南

     編輯:Java 相關知識

JDBC 4.0 XML 支持概覽

JDBC 4.0 (Java SE 6, JSR-221) 引入 java.sql.SQLXML 介面,標準化映射 SQL:2003 XML 數據類型。主流數據庫支援情況:

  • Oracle: XMLType
  • SQL Server: xml
  • DB2: XML
  • PostgreSQL: xml (需擴展)
  • MySQL: 5.7+ 無原生 XML 類型,常用 JSON 或 TEXT 替代

核心 API

// Connection 創建 SQLXML 對象
SQLXML sqlxml = conn.createSQLXML();

// 寫入 XML 數據(三種方式)
sqlxml.setString(xmlString);                    // 1. 字符串
sqlxml.setBinaryStream().write(xmlBytes);       // 2. 二進制流
sqlxml.setCharacterStream().write(xmlChars);    // 3. 字符流

// 綁定到 PreparedStatement
ps.setSQLXML(1, sqlxml); // 參數索引 1

// 讀取 ResultSet 中的 XML
SQLXML sqlxml = rs.getSQLXML("xml_column"); // 或 getSQLXML(1)
String xml = sqlxml.getString();             // 1. 字符串
InputStream is = sqlxml.getBinaryStream();   // 2. 二進制流
Reader reader = sqlxml.getCharacterStream(); // 3. 字符流

// 進階:轉換為 DOM/SAX/StAX/JAxB
DOMResult dom = new DOMResult();
sqlxml.getSource(DOMSource.class); // 獲取 Source
// 或
sqlxml.setResult(DOMResult.class); // 設置 Result
Document doc = (Document) dom.getNode();

完整示例:存儲與讀取文章 XML

public class XmlDbDemo {
    static final String[] ARTICLES = {
        "
FirstJohnShort.
", "
SecondMaryAnother.
", "
ThirdJohnLast.
" }; public static void main(String[] args) throws Exception { // 假設使用支援 JDBC 4.0 XML 的數據庫(如 Derby 10.14+ / Oracle / SQL Server) try (Connection conn = DriverManager.getConnection(url, user, pwd)) { createTable(conn); insertXml(conn); queryXml(conn); } } static void createTable(Connection conn) throws SQLException { try (Statement stmt = conn.createStatement()) { stmt.execute("CREATE TABLE articles (id INT PRIMARY KEY, content XML)"); } } static void insertXml(Connection conn) throws SQLException { String sql = "INSERT INTO articles (id, content) VALUES (?, ?)"; try (PreparedStatement ps = conn.prepareStatement(sql)) { for (int i = 0; i < ARTICLES.length; i++) { ps.setInt(1, i + 1); SQLXML sqlxml = conn.createSQLXML(); sqlxml.setString(ARTICLES[i]); ps.setSQLXML(2, sqlxml); ps.addBatch(); } ps.executeBatch(); } } static void queryXml(Connection conn) throws SQLException { String sql = "SELECT id, content FROM articles"; try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) { while (rs.next()) { int id = rs.getInt("id"); SQLXML sqlxml = rs.getSQLXML("content"); // 方式一:直接獲取字符串 String xml = sqlxml.getString(); System.out.println("ID=" + id + " XML=" + xml); // 方式二:解析為 DOM 文檔 DOMResult domResult = new DOMResult(); sqlxml.setResult(DOMResult.class); Document doc = (Document) domResult.getNode(); // XPath 查詢等... } } } }

Derby 測試環境說明

原文使用 Derby 10.2(不支援 SQLXML),現代版本 (10.14+) 已支援。若數據庫驅動未完全實現 SQLXML,常見回退方案:

  • 將 XML 存為 CLOB/TEXT:ps.setString(1, xml) / rs.getString(1)。
  • 應用層序列化:ps.setBytes(1, xml.getBytes(StandardCharsets.UTF_8))。

XML 與 Java 對象綁定 (JAXB)

// 寫入:對象 → XML → SQLXML
JAXBContext ctx = JAXBContext.newInstance(Article.class);
SQLXML sqlxml = conn.createSQLXML();
Result result = sqlxml.setResult(JAXBResult.class);
Marshaller marshaller = ctx.createMarshaller();
marshaller.marshal(article, result);
ps.setSQLXML(1, sqlxml);

// 讀取:SQLXML → XML → 對象
SQLXML sqlxml = rs.getSQLXML(1);
Source source = sqlxml.getSource(DOMSource.class);
Unmarshaller unmarshaller = ctx.createUnmarshaller();
Article article = (Article) unmarshaller.unmarshal(source);

最佳實踐

  1. 驗證驅動支援:`DatabaseMetaData.supportsSQLXML()` 檢查。
  2. 大 XML 使用流式讀寫:setBinaryStream()/getBinaryStream() 避免全量載入內存。
  3. 字符編碼一致性:數據庫、連接、JVM 均使用 UTF-8,避免亂碼。
  4. XML Schema 驗證:寫入前驗證 XSD,保證數據質量。
  5. 索引優化:數據庫層面對 XML 列建立路徑索引(如 SQL Server XML 索引、Oracle XMLIndex)。

總結

java.sql.SQLXML 為 JDBC 層面提供了標準化的 XML 類型訪問介面,支援字符串、流、DOM/SAX/StAX/JAXB 多種交互方式。雖然各數據庫廠商實現程度不一,但在支援原生 XML 類型的場景下(Oracle XMLType、SQL Server xml),使用 SQLXML 可避免手動序列化/反序列化,實現類型安全、流式處理與標準化綁定。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved