1. 理解Session的緩存:
在Java里面,緩存通常是指Java對象的屬性占用的內存空間,通常是一些集合類(lèi)型的屬性。在session接口的實(shí)現類(lèi)SessionImpl中定義了一系列的Java集合,這些Java集合就構成了Session的緩存。
當Session的save()方法持久化一個(gè)對象時(shí),這個(gè)對象被加入到Session的緩存中,以后即使應用程序中的引用變量不再引用這個(gè)對象,只要Session的緩存還沒(méi)有被清空,這個(gè)對象仍然處于生命周期中。當Session的load()方法加載一個(gè)對象時(shí),Session會(huì )先判斷緩存中是否已經(jīng)存在這個(gè)對象了,如果存在,就不需要再到數據庫中重新加載了。
Session的緩存有兩大作用:
1.1. 減少訪(fǎng)問(wèn)數據庫的頻率。
1.2. 保證緩存中的對象與數據庫中的相關(guān)記錄保持同步。
Session有兩個(gè)方法:一個(gè)commit()事務(wù)提交方法,還有flush()刷新緩存方法,都有著(zhù)清理緩存的作用。flush()進(jìn)行緩存的清理,執行一系列的SQL語(yǔ)句,但不會(huì )提交事務(wù)。而commit()方法會(huì )先調用flush()方法,然后在提交事務(wù)。
2. 定義持久化類(lèi)的建議:
在應用程序中,用來(lái)實(shí)現業(yè)務(wù)問(wèn)題實(shí)體的(如,在電子商務(wù)應用程序中的Customer和Order) 類(lèi)就是持久化類(lèi)。如果這些持久化類(lèi)遵循一些簡(jiǎn)單的規則,Hibernate能夠工作得更好,這些規則也被稱(chēng)作簡(jiǎn)單傳統Java對象(POJO:Plain Old Java Object)編程模型。但是這些規則并不是必需的。最好要遵循以下幾條主要的規則:
1) 實(shí)現一個(gè)默認的(即無(wú)參數的)構造方法(constructor):
我們強烈建議,在Hibernate中,為了運行期代理的生成,構造方法至少是 包(package)內可見(jiàn)的。
2) 提供一個(gè)標識屬性(identifier property):
我們建議你對持久化類(lèi)聲明命名一致的標識屬性。我們還建議你使用一個(gè)可以為空(也就是說(shuō),不是原始類(lèi)型)的類(lèi)型。
3) 使用非final的類(lèi):
代理(proxies)是Hibernate的一個(gè)重要的功能,它依賴(lài)的條件是,持久 化類(lèi)或者是非final的,或者是實(shí)現了一個(gè)所有方法都聲明為public的接口。你也應該避免在非final類(lèi)中聲明 public final的方法。
4) 為持久化字段聲明訪(fǎng)問(wèn)器(accessors):
5) 如果你有如下需求,你必須重載 equals() 和 hashCode()方法:
l 想把持久類(lèi)的實(shí)例放入Set中(當表示多值關(guān)聯(lián)時(shí),推薦這么做)
l 想重用脫管實(shí)例
Hibernate保證,僅在特定會(huì )話(huà)范圍內,持久化標識(數據庫的行)和Java標識是等價(jià)的。因此,一旦 我們混合了從不同會(huì )話(huà)中獲取的實(shí)例,如果希望Set有明確的語(yǔ)義,就必須實(shí)現equals() 和hashCode()。
3. 持久化對象的三種狀態(tài):
一個(gè)持久化類(lèi)的實(shí)例可能處于三種不同狀態(tài)中的某一種。
3.1. 瞬時(shí)(transient)狀態(tài):
該實(shí)例是剛用new語(yǔ)句創(chuàng )建的,還沒(méi)有被持久化,不處于任何Session的緩存中。它沒(méi)有持久化標識(相當于主鍵值)。處于瞬時(shí)狀態(tài)的實(shí)例被稱(chēng)為瞬時(shí)對象。它的特點(diǎn)是:
不和任何一個(gè)Session實(shí)例關(guān)聯(lián)。在數據庫中沒(méi)有對應的記錄。
3.2. 持久化 (persistent) 狀態(tài):
已經(jīng)被持久化,加入到Session緩存中。處于持久化狀態(tài)的實(shí)例被稱(chēng)為持久化對象。
實(shí)例目前與某個(gè)Session有關(guān)聯(lián)。 它擁有持久化標識(相當于主鍵值),并且可能在數據庫中有一個(gè)對應的行。 Hibernate保證在同一個(gè)Sesion實(shí)例的緩存中,數據庫中的每條記錄只對應唯一的持久化對象。 它的特點(diǎn)是:
持久化對象總是被一個(gè)Session實(shí)例關(guān)聯(lián)。持久化對象和數據庫中的相關(guān)記錄對應。Session在清理緩存時(shí),會(huì )根據持久化對象的屬性變化,來(lái)同步更新數據庫。
3.3. 脫管(detached) 狀態(tài):
已經(jīng)被持久化過(guò),但不再處于Session的緩存中。處于脫管狀態(tài)的實(shí)例被稱(chēng)為脫管對象。實(shí)例曾經(jīng)與某個(gè)持久化上下文發(fā)生過(guò)關(guān)聯(lián),不過(guò)那個(gè)上下文被關(guān)閉了, 或者這個(gè)實(shí)例是被序列化(serialize)到另外的進(jìn)程。 它擁有持久化標識,并且在數據庫中可能存在一個(gè)對應的行。 對于脫管狀態(tài)的實(shí)例,Hibernate不保證任何持久化標識和Java標識的關(guān)系。它的特點(diǎn)是:
不再位于session的緩存中,即它不再和session關(guān)聯(lián)。它擁有持久化標識。
4. Session的保存、刪除、更新和查詢(xún)方法:
4.1. Session的save()方法:使用一個(gè)臨時(shí)對象轉變?yōu)槌志脤ο蟆?div style="height:15px;">