Hibernate 3 引入開創性的 XML 持久化特性,允許將 XML 文檔直接映射到關係型數據庫,實現「對象-關係」(OR) 與「XML-關係」(XR) 統一建模。本文通過電子商務產品目錄同步案例,詳細演示映射配置、會話操作與最佳實踐。
Hibernate 3 內建採用 dom4j 作為 XML 解析/操作引擎,API 友好、性能優異。需確保類路徑包含 dom4j.jar、jaxen.jar (XPath 支援)。
供應商推送 XML 價格更新,在線零售商需實時同步至產品數據庫。
CREATE TABLE PRODUCT (
id INT PRIMARY KEY,
description VARCHAR(45) NOT NULL,
sku VARCHAR(45) UNIQUE NOT NULL,
list_price FLOAT,
base_price FLOAT,
order_price FLOAT
);
public class Product {
private int id;
private String sku;
private String description;
private Double listPrice;
private Double basePrice;
private Double orderPrice;
// Getter/Setter 省略
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example.model">
<class name="Product" table="product" node="product">
<id name="id" type="int" column="id" node="@prod_id">
<generator class="assigned"/> <!-- XML 提供 ID -->
</id>
<property name="sku" column="sku" node="@sku" not-null="true"/>
<property name="description" column="description" node="description" not-null="true"/>
<property name="listPrice" column="list_price" node="list_price"/>
<property name="basePrice" column="base_price" node="drop_price"/> <!-- XML 節點名不同 -->
<property name="orderPrice" column="order_price"/> <!-- 無 node,僅 OR 映射 -->
</class>
</hibernate-mapping>
node 詳細語法| 語法 | 含義 | 示例 |
|---|---|---|
node="element-name" | 映射到子元素 | node="description" → <description>...</description> |
node="@attribute-name" | 映射到屬性 | node="@sku" → <product sku="1001"> |
node="." | 映射到父元素 (當前上下文) | 罕用,用於組合映射 |
node="element-name/@attr" | 映射到指定元素的屬性 | node="product/@prod_id" |
無 node | 僅參與 OR 映射,忽略 XML | orderPrice 僅存數據庫 |
<products>
<product prod_id="3" sku="100101">
<description>Athlete mode body fat scale</description>
<list_price>100.00</list_price>
<drop_price>60.00</drop_price> <!-- 對應 basePrice -->
</product>
<product prod_id="4" sku="100102">
<description>Thermometer</description>
<list_price>20.00</list_price>
<drop_price>11.00</drop_price>
</product>
</products>
public void syncProductsFromXml(InputStream xmlInput) {
Session session = null;
Transaction tx = null;
try {
// 1. 解析 XML 文檔 (dom4j)
SAXReader reader = new SAXReader();
Document document = reader.read(xmlInput);
List<Node> productNodes = document.selectNodes("//product"); // XPath 查詢
// 2. 獲取 Hibernate 會話並開啟事務
session = sessionFactory.openSession();
tx = session.beginTransaction();
// 3. 關鍵:打開 DOM4J 模式的會話
Session dom4jSession = session.getSession(EntityMode.DOM4J);
// 4. 批量保存/更新
for (Node productNode : productNodes) {
// saveOrUpdate 自動判斷新增/更新 (基於 ID)
dom4jSession.saveOrUpdate("com.example.model.Product", productNode);
}
tx.commit();
System.out.println("同步完成,處理產品數: " + productNodes.size());
} catch (Exception e) {
if (tx != null) tx.rollback();
throw new RuntimeException("XML 同步失敗", e);
} finally {
if (session != null) session.close();
}
}
EntityMode.DOM4J:告知 Hibernate 當前操作 dom4j 節點而非 POJOsaveOrUpdate(entityName, object):entityName 對應映射文件 class name,object 為 dom4j Node@prod_id 自動匹配數據庫 id 列,實現冪等更新// POJO 轉 XML (導出)
Session dom4jSession = session.getSession(EntityMode.DOM4J);
Product product = (Product) session.get(Product.class, 3);
Node productNode = (Node) dom4jSession.get("com.example.model.Product", 3);
// productNode 即為 dom4j Element,可輸出 XML
// XML 轉 POJO (導入) - 上文已演示
<!-- 一對多:訂單包含多個項目 -->
<class name="Order" table="orders" node="order">
<id name="id" node="@id"/>
<set name="items" node="items" cascade="save-update">
<key column="order_id"/>
<one-to-many class="OrderItem" node="item"/>
</set>
</class>
session.setJdbcBatchSize(50) + 定期 flush()/clear()session.setDefaultReadOnly(true)StAX 分塊解析,避免全量載入 DOM 內存Gavin King 明確指出:Hibernate XML 特性是 OR 核心能力的「有用擴展」,而非專業 XML 編組/轉換框架 (如 JAXB, JiBX, XStream) 的替代品。
| 場景 | 推薦方案 |
|---|---|
| 簡單 XML ↔ 關係表同步 | Hibernate XML 持久化 |
| 複雜 XML Schema 驗證、XSLT 轉換、流式處理 | JAXB / Saxon / StAX |
| 高性能 XML 序列化/反序列化 | JiBX / FastInfoset |
| 圖數據/文檔數據庫 | Neo4j / MongoDB / MarkLogic |
Hibernate 3 XML 持久化以極低學習成本 (復用 OR 映射語法)、零額外依賴 (內建 dom4j)、統一事務語義,為「XML 數據入庫」場景提供了極具性價比的解決方案。適用於異構系統集成、數據同步、歸檔審計等中低復雜度 XML 落地場景。