Hibernate實戰讀書摘要(2)—領域模型和元數據

Hibernate不要求持久化類實現Serializable(可序列化)。然而,當對象被存儲在一個HttpSession中,或者用RMI按值傳遞時,就需要序列化。(這可能發生在Hibernate應用程序中。)類可以是抽象的,必要時,可以擴展非持久化的類。

Hibernate髒檢查

Hibernate自動偵測對象狀態的改變,以便使更新過的狀態與數據庫同步。從獲取方法返回一個不同的對象,通常比由Hibernate傳遞到設置方法的對象來得安全。Hibernate按值比較對象——不是按對象同一性——來確定一個屬性的持久化狀態是否需要被更新。

這有個重要的例外:集合是按同一性比較的!對於一個被映射爲持久化集合的屬性,你應該從獲取方法中返回與Hibernate傳遞到設置方法中完全相同的集合實例。如果沒有,Hiberntae將更新數據庫,即使不需要更新,保存在內存中的狀態每次也都會與數據庫同步。


全局的註解元數據

註解天生就被織入一個特定類的Java源代碼中。雖然可能把全局的註解放在類的源文件中(在頂部),我們還是喜歡把全局的元數據放在一個單獨的文件中。這稱作包元數據(package metadata),它被特定包目錄中具名package-info.java的文件所啓用。


Hibernate其他實體表示法

Hibernate中有3種內建的實體模式:

POJO——基於POJO、持久化類的一種領域模型實現。這是目前爲止你所見到的,是默認的實體模式。

MAP——不需要Java類:用HashMap在Java應用程序中表示實體。這個模式允許完全動態應用程序的快速原型。

DOM4J——不需要Java類:實體被表示爲XML元素,基於dom4j API。這種模式對於導出或者導入數據,或者通過XSLT處理來渲染和轉換數據時特別有用。

可以在動態模式中映射一個Set(集)嗎?基於set集合不適用於動態的實體模式。Set在它的元素中檢查重複元素,因此當你調用add(item1)和add(item2)時,這些對象中的equals方法也被調用,然而,item1和item2是Java Map實例,一個映射的equals()實現基於映射的鍵組。因此,由於item1和item2是帶有相同鍵的映射,因此當他們被添加給一個Set時,並沒有明顯的區別。只有當你在動態的實體模式中需要集合時才使用bag或者list。

有時需要把POJO模型與動態Map混合。爲什麼要把領域沒模型的靜態實現與動態映射表示法混合起來,有兩個原因:

一、你要默認使用基於POJO類的靜態模型,但有時候要把數據輕鬆地表示爲映射的映射。這在生成報表時,或者必須實現一個可以動態地表示不同實體的普通用戶界面時,特別有用。

二、要把模型的單個POJO類映射到幾張表,然後通過指定一個邏輯的實體名稱在運行時選擇表。


表示XML中的數據

Hibernate沒有內建的功能 來存儲XML格式的數據:它依賴於關係表示和SQL,這種策略的好處應該很清楚。另一方面,Hibernate能夠以XML格式把數據加載和呈現給應用程序的開發人員。它允許你使用一組複雜的工具,而無需任何額外的轉換步驟。

假設你在默認的POJO模式下工作,並且很快想要獲得一些以XML表示的數據。用EntityMode.DOM4J打開一個臨時的Session:

Session dom4jSession = session.getSession(EntityMode.DOM4J);
Element userXML = (Element) dom4jSession.load(User.class, storedUserId);

此處返回的是一個dom4j Element,可以用這個dom4j API來讀取和操作它。例如,可以用下列片段把它很漂亮地打印到控制檯:

try {
	OutputFormat format = OutputFormat.createPrettyPrint();
	XMLWriter writer = new XMLWriter(System.out, format);
	writer.write(userXML);
} catch (IOException ex) {
	throw new RuntimeException(ex)
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章