首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 9 pureXML 實戰體驗:原生 XML 存儲、查詢、更新與 JDBC 整合全攻略

     編輯:DB2 教學

前言:pureXML —— 關係與 XML 融合的範式變革

經過 5 年研發,DB2 9 (代號 Viper) 推出 pureXML 技術,以原生層次模型存儲 XML,避免 CLOB 文本或關係映射的效能與靈活性損耗。DB2 9 在同一資料列、同一張表中實現關係數據與 XML 數據的無縫融合,支援 SQL/XML (SQL + XQuery) 混合查詢,靈活索引加速 XML 檢索。本文基於 SAMPLE 資料庫 CUSTOMER 表,通過 JDBC Type 4 驅動完整演示 XML 插入、查詢 (XMLEXISTS/XMLQUERY/XMLTABLE)、更新、刪除操作,並附完整 Java 代碼範例。

一、環境準備與表結構

SAMPLE 資料庫 CUSTOMER 表包含三欄:

  • CID (INTEGER, PK)
  • INFO (XML) —— 客戶完整資訊 (地址、電話、傳真等)
  • HISTORY (XML) —— 歷史記錄

關鍵特性:XML 欄無需預定義 Schema,單欄可存儲不同 Schema 或無 Schema 的任意合法 XML 文檔。

CUSTOMER 表結構

二、JDBC 連接配置

1. 四類 JDBC 驅動架構回顧

2. 通用驅動連接範例


// 載入驅動
Class.forName("com.ibm.db2.jcc.DB2Driver");

// 連接 URL 格式
String url = "jdbc:db2://<host>:<port>/<db>";
// 例:jdbc:db2://localhost:50000/SAMPLE

// 屬性配置
Properties props = new Properties();
props.setProperty("user", "Administrator");
props.setProperty("password", "lys");
Connection conn = DriverManager.getConnection(url, props);

3. 外部屬性檔 (db2Conn.properties)


# JDBC 配置
hostName=localhost
portNumber=50000
databaseName=SAMPLE
userName=Administrator
passWord=lys
# XML 檔案路徑
fileName=F:\\eclipse\\WorkPlace\\DB2XML\\src\\p5.xml

4. 連接工具類 (db2Conn.java)


public class db2Conn {
    public static Connection get(String db, String user, String pwd, String host, String port) {
        Connection conn = null;
        try {
            Class.forName("com.ibm.db2.jcc.DB2Driver");
            String databaseURL = "jdbc:db2://" + host + ":" + port + "/" + db;
            Properties props = new Properties();
            props.setProperty("user", user);
            props.setProperty("password", pwd);
            conn = DriverManager.getConnection(databaseURL, props);
            if (conn == null) System.out.println("Connection Failed");
        } catch (Exception e) { e.printStackTrace(); System.exit(-1); }
        return conn;
    }
}

三、XML 插入操作 (insertXML.java)

核心技巧:使用 PreparedStatement.setBinaryStream() 直接流式寫入 XML 文件,避免記憶體壓力。


public class Test2 {
    public static void main(String[] args) throws Exception {
        // 載入屬性檔、建立連接 (同上)
        Connection conn = db2Conn.get(db, userName, passwd, host, port);
        int id = 99;  // PK,重複執行需修改或設自增
        String fn = "F:\\eclipse\\WorkPlace\\DB2XML\\src\\Client8877.xml";
        String sql = "INSERT INTO CUSTOMER (CID, INFO) VALUES (?, ?)";
        
        File file = new File(fn);
        PreparedStatement stmt = conn.prepareStatement(sql);
        conn.setAutoCommit(true);
        stmt.setInt(1, id);
        stmt.setBinaryStream(2, new FileInputStream(file), (int) file.length());
        if (stmt.executeUpdate() == 1) 
            System.out.println("Insert successful");
        stmt.close();
        conn.close();
    }
}

四、XML 查詢操作 (readXML.java)

使用 ResultSet.getString() 直接獲取 XML 序列化字串,或 getBinaryStream() 流式讀取。


public static String getDescription(String cid) {
    String desc = null;
    try {
        PreparedStatement stmt = conn.prepareStatement("SELECT INFO FROM CUSTOMER WHERE CID = ?");
        stmt.setString(1, cid);
        ResultSet rs = stmt.executeQuery();
        if (rs.next()) desc = rs.getString(1);
        else System.out.println("Customer not found");
        rs.close(); stmt.close();
    } catch (SQLException e) { /* 錯誤處理、回滾、退出 */ }
    return desc;
}

查詢結果示例

五、進階 SQL/XML 查詢函數

1. XMLEXISTS —— 依 XML 內容過濾行

查找郵遞區號 95116 的客戶姓名:


SELECT NAME FROM CUSTOMER
WHERE XMLEXISTS('$c/Client/Address[Zip="95116"]' PASSING CUSTOMER.INFO AS "c")
  • $c/Client/Address[Zip="95116"]:XPath 表達式,$c 為上下文變數
  • PASSING INFO AS "c":將 XML 欄綁定到變數 $c
  • 返回布林值,用於 WHERE 子句

2. XMLQUERY —— 投影單一 XML 元素值

列出狀態為 'good' 客戶的 Email:


SELECT XMLQUERY('$c/Client/Email' PASSING INFO AS "c") FROM CUSTOMER WHERE STATUS = 'good'

返回 XML 片段 (如 <Email>user@example.com</Email>)。

3. XMLTABLE —— 將 XML 節點映射為關係結果集

將 XML 多節點展開為多行多欄:


SELECT XT.* FROM CUSTOMER,
XMLTABLE('$c/Client/Phone' PASSING INFO AS "c"
  COLUMNS 
    TYPE VARCHAR(10) PATH '@Type',
    NUMBER VARCHAR(20) PATH '.'
) AS XT

產出關係表格,可直接 JOIN、聚合。

六、XML 更新操作

1. SQL UPDATE 方式 (需提供完整文檔)


UPDATE CLIENTS SET CONTACTINFO = XMLPARSE(DOCUMENT '<Email>new@email.com</Email>') WHERE ID = 3227

缺點:即使只改 Email,也需傳入完整 ContactInfo 文檔。

2. 系統存儲過程 XMLUPDATE (僅更新指定節點)


CALL DB2XMLFUNCTIONS.XMLUPDATE(?, ?, ?)  -- 參數:表名、XPath、新值

優點:無需讀取/傳輸完整文檔,細粒度更新,效能優。

3. Java 完整更新範例 (updateXML.java 核心邏輯)


// 1. 查詢現有 XML 文檔
String xml = getProduct(pID);  // 同查詢邏輯

// 2. 使用 DOM 解析並修改指定節點
Document doc = parse(xml);
setValue("/product/description/price/text()", "99.99");  // XPath 定位

// 3. 更新回資料庫
PreparedStatement stmt = conn.prepareStatement("UPDATE CUSTOMER SET INFO = ? WHERE CID = ?");
stmt.setString(1, serialize(doc));
stmt.setString(2, pID);
stmt.executeUpdate();

範例代碼採用 Apache Xerces DOM 實現,支援互動式選單修改多欄位。

七、XML 刪除操作

1. 刪除整行


DELETE FROM CUSTOMER WHERE CID = 1000

2. 依 XML 內容刪除 (配合 XMLEXISTS)


DELETE FROM CLIENTS
WHERE XMLEXISTS('$c/Client/Address[Zip="95116"]' PASSING CONTACTINFO AS "c")

八、最佳實踐總結

  1. Unicode 資料庫強制:僅 Unicode DB 支援 XML + 傳統類型混存
  2. Type 4 驅動首選:無需客戶端庫,部署簡單,效能佳
  3. 流式處理大 XML:setBinaryStream/getBinaryStream 避免 OOM
  4. 細粒度更新用 XMLUPDATE:避免全文檔往返
  5. 混合查詢善用 XMLTABLE:將 XML 關係化,發揮 SQL 優化器優勢
  6. 索引策略:針對高頻 XPath 路徑建立 XML 索引,大幅提升 XMLEXISTS/XMLQUERY 效能
  7. Schema 演進無痛:無需 ALTER TABLE,新結構直接寫入,舊文檔兼容共存

DB2 9 pureXML 徹底消除了「關係或 XML」的二元對立,讓開發者在同一平台上以最適合的資料模型解決問題。立即下載 DB2 Express-C 體驗原生 XML 的威力!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類型特點代表
Type 1JDBC-ODBC 橋接,依賴本地庫,可移植性差JDBC-ODBC Bridge
Type 2Java + 本地代碼,需部署 DB2 客戶端庫COM.ibm.db2.jdbc.app.DB2Driver
Type 3純 Java 客戶端 + 中間件服務器COM.ibm.db2.jdbc.Net.DB2Driver
Type 4純 Java,直連資料庫網絡協議 (推薦)com.ibm.db2.jcc.DB2Driver (db2jcc.jar)