大型商業資料庫紛支援原生 XML 儲存,但標準尚未成熟,架構師常面臨:廠商鎖定風險 或 自建整合框架成本高、難維護。Hibernate 3 將 ORM 成熟機制延伸至 XML,提供跨資料庫平台、一致程式模型的整合方案。
<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>
</product>
...
</products>
CREATE TABLE PRODUCT (
id INT PRIMARY KEY,
description VARCHAR(45),
sku VARCHAR(45) UNIQUE,
list_price FLOAT,
base_price FLOAT,
order_price FLOAT
);
public class Product {
int id; String sku; String description;
Double listPrice, basePrice, orderPrice;
// getter/setter 省略
}
<hibernate-mapping package="demo">
<class name="Product" table="product" node="product">
<id name="id" type="int" node="@prod_id" column="id"></id>
<property name="sku" node="@sku" column="sku" not-null="true"/>
<property name="description" node="description" column="description" not-null="true"/>
<property name="listPrice" node="list_price" column="list_price"/>
<property name="basePrice" node="drop_price" column="base_price"/>
<property name="orderPrice" column="order_price"/> <!-- 無 node,僅資料庫欄位 -->
</class>
</hibernate-mapping>
node 語法| 語法 | 對應 XML 結構 | 範例 |
|---|---|---|
element-name | 子元素 | node="product" → <product>...</product> |
@attribute-name | 屬性值 | node="@sku" → <product sku="..."> |
. | 父元素 | node="." → <products>(相對 product) |
element-name/@attr | 指定元素的屬性 | node="product/@sku" |
Document doc = saxReader.read(inputXML);
List nodes = doc.selectNodes("//product");
Session session = HibernateUtil.sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Session dom4jSession = session.openSession(EntityMode.DOM4J);
for (Object node : nodes) {
dom4jSession.saveOrUpdate("demo.Product", node);
}
tx.commit();
session.close();
核心:開啟 EntityMode.DOM4J 的 Session,直接以 dom4j 節點物件執行 saveOrUpdate,Hibernate 依映射檔自動同步至關聯資料表。
「XML 持久化不是 Hibernate 的主要任務,它是強大 ORM 框架的有用擴展。複雜 XML 轉換、編組仍應使用專門框架(如 JAXB、XStream、DOM4J 本身)。」—— Gavin King
適用場景:接收外部 XML 餾資料、需同步至關聯資料庫的整合案例。不適用:複雜 XML 結構重組、XSLT 轉換、Schema 驗證等純 XML 處理密集場景。