Hibernate學(xué)習(xí)筆記
1、Hibernate核心類與接口
1-1.Configuration類
Configuration類是Hibernate的入口,它負(fù)責(zé)配置和啟動(dòng)Hibernate,Hibernate框架通過(guò)Configuration實(shí)例加載配置文件信息(hibernate.cfg.xml),然后讀取指定對(duì)象關(guān)系映射文件(bean.hbm.xml)的內(nèi)容并創(chuàng)建SessionFactory.
1-2.SessionFactory接口
SessionFactory接口負(fù)責(zé)初始化Hibernate,一個(gè)SessionFactory實(shí)例對(duì)應(yīng)一個(gè)數(shù)據(jù)存儲(chǔ)源(一般就是指一個(gè)數(shù)據(jù)庫(kù))。應(yīng)用程序從SessionFactory中獲得Session實(shí)例。SessionFactory具有以下特點(diǎn):
1) 線程安全,即同一個(gè) SessionFactory實(shí)例可以被應(yīng)用 的多個(gè)線程共享。
2) 它是重量級(jí)的 ,因?yàn)樗枰粋€(gè)很大的緩存,用來(lái)存放預(yù)定義的SQL語(yǔ)句以及映射元數(shù)據(jù)等。
所以說(shuō) ,如果一個(gè)應(yīng)用程序中只訪問(wèn)一個(gè)數(shù)據(jù)庫(kù) ,則只需要?jiǎng)?chuàng)建一個(gè)全局的 SessionFactory實(shí)例。
1-3.Session 接口
Session是Hibernate中應(yīng)用最頻繁的接口。Session也被稱為持久化管理器 ,它負(fù)責(zé)管理所有與持久化相關(guān)的操作:如存儲(chǔ)、更新、刪除和加載對(duì)象等。Session接口具有以下特點(diǎn):
1) 單線程,非共享的對(duì)象。線程不安全,在設(shè)計(jì)軟件架構(gòu)時(shí)候,應(yīng)該避免多個(gè)線程共享同一個(gè)session實(shí)例。
2) Session 實(shí)例是輕量級(jí)的,它的創(chuàng)建和銷毀不需要消耗太多的資源。可以為每個(gè)請(qǐng)分配一個(gè)Session實(shí)例,在每次請(qǐng)求過(guò)程匯總及時(shí)創(chuàng)建和銷毀 Session實(shí)例。
3) Session有一個(gè)緩存,它存放當(dāng)前工作單元加載的對(duì)象。Session的緩存被稱為Hibernate的一級(jí)緩存。
1-4.Transaction接口
Transaction接口是 Hibernate框架的事務(wù)接口。它對(duì)底層的事務(wù)接口做了封裝,包括:JDBC API和JTA.這樣使得Hibernate應(yīng)用可以通過(guò)一致的Transaction接口來(lái)申明事務(wù)邊界,這有助于應(yīng)用程序再不同的環(huán)境和容器中移植。
1-5.Query和Criteria接口
它們是 Hibernate的查詢接口,用于從數(shù)據(jù)存儲(chǔ)源查詢對(duì)象及控制執(zhí)行查詢的過(guò)程。Query包裝了一個(gè) HQL(Hibernate Query Language);而Criteria接口完全封裝了基本字符串形式的查詢語(yǔ)句,比Query更加面向?qū)ο螅?/span>Criteria接口擅長(zhǎng)于執(zhí)行動(dòng)態(tài)查詢。
2、Hibernate中常用的事務(wù)隔離級(jí)別
常量 |
值 |
說(shuō)明 |
TRANSACTION_NONE |
0 |
不支持事務(wù) |
TRANSACTION_READ_UNCOMMITTED |
1 |
指示可以發(fā)生臟讀(dirty read)、不可重復(fù)讀和虛讀(phantom read)的常量。此級(jí)別允許被某一事務(wù)更改的行在已提交該行所有更改之前被另一個(gè)事務(wù)讀取(“臟讀”)。如果所有更改都被回滾,則第二個(gè)事務(wù)將獲取無(wú)效的行。 |
TRANSACTION_READ_COMMITTED |
2 |
指示不可以發(fā)生臟讀的常量;不可重復(fù)讀和虛讀可以發(fā)生。此級(jí)別只禁止事務(wù)讀取其中帶有未提交更改的行。 |
TRANSACTION_REPEATABLE_READ |
4 |
指示不可以發(fā)生臟讀和不可重復(fù)讀的常量;虛讀可以發(fā)生。此級(jí)別禁止事務(wù)讀取帶有未提交更改的行,它還禁止這種情況:一個(gè)事務(wù)讀取某一行,而另一個(gè)事務(wù)更改該行,第一個(gè)事務(wù)重新讀取該行,并在第二次讀取時(shí)獲得不同的值(“不可重復(fù)讀”)。 |
TRANSACTION_SERIALIZABLE |
8 |
指示不可以發(fā)生臟讀、不可重復(fù)讀和虛讀的常量。此級(jí)別包括TRANSACTION_REPEATABLE_READ 中禁止的事項(xiàng),同時(shí)還禁止出現(xiàn)這種情況:某一事務(wù)讀取所有滿足 WHERE 條件的行,另一個(gè)事務(wù)插入一個(gè)滿足 WHERE 條件的行,第一個(gè)事務(wù)重新讀取滿足相同條件的行,并在第二次讀取時(shí)獲得額外的“虛”行。 |
3、Hibernate中實(shí)例的狀態(tài)
3-1:臨時(shí)狀態(tài)
該實(shí)例從未與任何持久化上下文關(guān)聯(lián)過(guò)。它沒(méi)有持久化標(biāo)識(shí)(相當(dāng)于主鍵值),臨時(shí)狀態(tài)下的對(duì)象有如下特征。
1) 不處于Session緩存中,也可以說(shuō)不被任何一個(gè)Session關(guān)聯(lián)
2) 在數(shù)據(jù)庫(kù)中沒(méi)有對(duì)應(yīng)的記錄
在以下情況下,Java對(duì)象進(jìn)入臨時(shí)狀態(tài)
1) 當(dāng)通過(guò)new語(yǔ)句剛創(chuàng)建一個(gè)Java對(duì)象,它處于臨時(shí)狀態(tài),此時(shí)不和數(shù)據(jù)庫(kù)中的任何記錄對(duì)應(yīng)。
2) Session的delete()方法能使一個(gè)持久化或臨時(shí)脫管對(duì)象轉(zhuǎn)換為臨時(shí)對(duì)象。對(duì)于脫管對(duì)象,delete()方法從數(shù)據(jù)庫(kù)中刪除與它對(duì)應(yīng)的記錄,并且把它從Session緩存中刪除。
3-2:持久化狀態(tài)
該實(shí)例目前與某個(gè)持久化上下文有關(guān)聯(lián),它擁有持久化標(biāo)識(shí)(相當(dāng)于主鍵值),并且可能在數(shù)據(jù)庫(kù)匯總有一個(gè)對(duì)應(yīng)的行。對(duì)于某一個(gè)特定的持久化上下文,Hibernate保證標(biāo)識(shí)與Java標(biāo)識(shí)(其值代表對(duì)應(yīng)在內(nèi)存中的位置)等價(jià)。持久化對(duì)象有以下特征。
1) 位于一個(gè)Session實(shí)例的緩存中,也可以說(shuō),持久化對(duì)象總是被一個(gè)Session實(shí)例關(guān)聯(lián)。
2) 持久化對(duì)象和數(shù)據(jù)庫(kù)中的相關(guān)記錄對(duì)應(yīng)。
3) Session在清理緩存時(shí),會(huì)根據(jù)持久化對(duì)象的屬性變化,來(lái)同步更新數(shù)據(jù)庫(kù)。
Session的許多方法都能夠觸發(fā)Java對(duì)象進(jìn)入持久化狀態(tài)。
4) Session的save()的方法能夠把臨時(shí)對(duì)象轉(zhuǎn)變成持久化對(duì)象。
5) Session的load()或get()方法返回的對(duì)象總是處于持久化狀態(tài)。
6) Query類的list()方法返回的list集合中存放的都是持久化對(duì)象。
7) Session的update()、saveOrUpdate()和lock()方法使脫管對(duì)象轉(zhuǎn)變?yōu)槌志没瘜?duì)象。
當(dāng)一個(gè)持久化對(duì)象關(guān)聯(lián)一個(gè)臨時(shí)對(duì)象時(shí),在允許級(jí)聯(lián)保存的情況下,Session在清理緩存時(shí)會(huì)把這個(gè)臨時(shí)對(duì)象也轉(zhuǎn)變成持久化對(duì)象。Hibernate保證在同一個(gè)Session實(shí)例的緩存中,數(shù)據(jù)庫(kù)表中的每條記錄只對(duì)應(yīng)唯一的持久化對(duì)象,也就是說(shuō)在一個(gè)Session里load/get同一個(gè)OID得到 的是相同的對(duì)象。
3-3:脫管狀態(tài)
實(shí)例曾經(jīng)與某個(gè)持久化上下文發(fā)生過(guò)關(guān)聯(lián),不過(guò)那個(gè)上下文被關(guān)閉了,或者這個(gè)實(shí)例是被序列化(serialize)到另外的進(jìn)程。它擁有持久化標(biāo)識(shí),并且在數(shù)據(jù)庫(kù)中可能存在一個(gè)對(duì)應(yīng)的行。對(duì)于脫管狀態(tài)的實(shí)例,Hibernate不保證任何持久化標(biāo)識(shí)和Java標(biāo)識(shí)的關(guān)系。
脫管對(duì)象具有以下特征。
1) 不再位于Session的緩存中,也可以說(shuō),脫管對(duì)象不被Session關(guān)聯(lián)。
2) 脫管對(duì)象是有持久化對(duì)象轉(zhuǎn)變過(guò)來(lái)的,因此在數(shù)據(jù)庫(kù)中可能還存在與它對(duì)應(yīng)的記錄(前提條件是沒(méi)有其他程序刪除了這條記錄)。
3) 脫管對(duì)象與臨時(shí)對(duì)象的相同指出在于兩者都不被Session關(guān)聯(lián),因此Hibernate不會(huì)保證他們屬性變化與數(shù)據(jù)庫(kù)保持同步。脫管對(duì)象與臨時(shí)對(duì)象的區(qū)別在于前者是由持久化對(duì)象轉(zhuǎn)變過(guò)來(lái)的,因此可能在書庫(kù)中還存在對(duì)應(yīng)的記錄,而后者在數(shù)據(jù)庫(kù)中是沒(méi)有對(duì)應(yīng)的記錄的。
Session的以下方法使持久化對(duì)象轉(zhuǎn)變成脫管對(duì)象.
1) 當(dāng)調(diào)用Session的close()方法時(shí),Session 的緩存被清空,緩存中的所有持久化對(duì)象都變?yōu)槊摴軐?duì)象,如果在應(yīng)用程序中沒(méi)有引用變量引用這些脫管對(duì)象,他們就會(huì)結(jié)束生命周期。
2) Session的evict()方法能夠從緩存中刪除一個(gè)持久化對(duì)象,使它變?yōu)槊摴軤顟B(tài),當(dāng)Session的緩存中保存了大量的持久化對(duì)象時(shí),會(huì)消耗許多內(nèi)存空間,為了提高性能,可以考慮調(diào)用evict()方法,從緩存中刪除一些持久化對(duì)象。但是多數(shù)情況下不推薦使用該方法,而應(yīng)該通過(guò)查詢語(yǔ)言,或者顯示的導(dǎo)航來(lái)控制對(duì)象圖的深度。