目錄:(后續(xù)不斷更新...)
- Hibernate 入門 01 - 框架技術(shù) (介紹Hibernate框架的發(fā)展由來)
- Hibernate 入門 02 - Hibernate介紹及其環(huán)境搭建
- Hibernate 入門 03 - 使用Hibernate完成持久化操作
- Hibernate 入門 04 - Hibernate中java對象的三種狀態(tài)
當(dāng)應(yīng)用通過調(diào)用Hibernate API與框架發(fā)生交互時(shí),需要從持久化的角度關(guān)注應(yīng)用對象的生命周期。
持久化聲明周期是Hibernate中的一個(gè)關(guān)鍵概念,正確地理解生命周期,可以更好地了解Hibernate的實(shí)現(xiàn)原理,掌握Hibernate的正確用法。
Hibernate框架通過session來管理Java對象的狀態(tài),在持久化生命周期中,Java對象存在著如下三種狀態(tài):
瞬時(shí)狀態(tài)(Transient)
通過new創(chuàng)建對象后,對象并沒有l(wèi)ike持久化,它并未與數(shù)據(jù)庫中的數(shù)據(jù)有任何關(guān)聯(lián),此時(shí)Java對象的狀態(tài)為瞬時(shí)狀態(tài)。
Session對于瞬時(shí)狀態(tài)的Java對象是一無所知的,當(dāng)對象不再被其他對象引用時(shí),它的所有數(shù)據(jù)也就丟失了,對象將會(huì)被Java虛擬機(jī)按照垃圾回收機(jī)制處理。
持久狀態(tài)(Persistent)
當(dāng)對象與Session關(guān)聯(lián),被Session管理時(shí),它就處于持久狀態(tài)。處于持久狀態(tài)的對象擁有數(shù)據(jù)庫標(biāo)識(shí)(數(shù)據(jù)庫中的主鍵值)。
那么,對象是什么時(shí)候與Session發(fā)生關(guān)聯(lián)的呢?有兩種方法:
第一種,通過Sesison的查詢接口,或者get()方法,或者load()方法從數(shù)據(jù)庫中加載對象的時(shí)候,加載的對象是與數(shù)據(jù)庫表中的一條記錄關(guān)聯(lián)的,此時(shí)對象與加載它的Session發(fā)生關(guān)聯(lián);
第二種,瞬時(shí)狀態(tài)的對象,通過Session的save()方法或SaveOrUpdate()方法時(shí),Java對象也與Session發(fā)生關(guān)聯(lián)。
對于處于持久狀態(tài)的對象,Session會(huì)持續(xù)跟蹤和管理它們,如果對象的內(nèi)部狀態(tài)發(fā)生了任何變更,Hibernate會(huì)選擇合適的時(shí)機(jī)(如事務(wù)提交時(shí))將變更固化到數(shù)據(jù)庫中。
游離狀態(tài)
處于持久狀態(tài)的對象,脫離與其關(guān)聯(lián)的nSession的管理后,對象就處于游離狀態(tài)。
處于游離狀態(tài)的對象,Session無法保證對象所包含的數(shù)據(jù)與數(shù)據(jù)庫中的記錄一直,因?yàn)镠ibernate已經(jīng)無法感知對該對象的任何操作。
Session提供了兩個(gè)方法(update()、merge()),將處于游離狀態(tài)的對象,與一個(gè)新的Session發(fā)生關(guān)聯(lián)。
此時(shí),對象的狀態(tài)就從游離狀態(tài)重新轉(zhuǎn)換為持久狀態(tài)。
在Hibernate應(yīng)用中,不同的持久化操作會(huì)導(dǎo)致對象狀態(tài)的改變。如圖描述了對象狀態(tài)的轉(zhuǎn)換:
使用new關(guān)鍵字構(gòu)建對象,該對象的狀態(tài)是瞬時(shí)狀態(tài)。
2.1 瞬時(shí)狀態(tài)轉(zhuǎn)為持久狀態(tài)
使用Session對象的save()或saveOrUpdate()方法保存對象后,該對象的狀態(tài)由瞬時(shí)狀態(tài)轉(zhuǎn)換為持久狀態(tài)。
使用Session對象的get()或load()方法獲取對象,該對象的狀態(tài)是持久狀態(tài)。
2.2 持久狀態(tài)轉(zhuǎn)為瞬時(shí)狀態(tài)
執(zhí)行Session對象的delete()方法后,對象由原來的持久狀態(tài)變?yōu)樗矔r(shí)狀態(tài),因?yàn)榇藭r(shí)該對象沒有與任何的數(shù)據(jù)庫數(shù)據(jù)關(guān)聯(lián)。
2.3 持久狀態(tài)轉(zhuǎn)為游離狀態(tài)
吃行了Session對象的evict()、clear()或close()方法,對象由原來的持久狀態(tài)轉(zhuǎn)為游離狀態(tài)。
2.4 游離狀態(tài)轉(zhuǎn)為持久狀態(tài)
重新獲取Session對象,執(zhí)行Session對象的update()或saveOrUpdate()方法,對象由游離狀態(tài)轉(zhuǎn)為持久狀態(tài),該對象再次與Session對象相關(guān)聯(lián)。
2.5 游離狀態(tài)轉(zhuǎn)為瞬時(shí)狀態(tài)
執(zhí)行Session對象的delete()方法,對象由游離狀態(tài)轉(zhuǎn)為瞬時(shí)狀態(tài)。
處于瞬時(shí)狀態(tài)或游離狀態(tài)的對象不再被其他對象引用時(shí),會(huì)被Java虛擬機(jī)按照垃圾回收機(jī)制處理。
需求:為以下兩段代碼補(bǔ)充語句,輸出各個(gè)階段對象的狀態(tài)。
代碼1:
1 try{ 2 // 省略部分代碼... 3 session = sessionFactory.openSession(); 4 tx = session.beginTransaction(); // 開始一個(gè)事務(wù) 5 User user = (User)session.load(User.class, new Integer("1001")); // 獲取用戶對象 6 user.setUsername("張董"); // 修改用戶信息 7 tx.commit(); // 提交事務(wù) 8 }catch(HibernateException e){ 9 e.PRintStackTrace();10 tx.rollback(); // 回滾事務(wù)11 }finally{12 if(null != session){13 session.close(); // 關(guān)閉session14 }15 }
代碼2:
1 try{ 2 // 省略部分代碼 3 session = sessionFactory.openSession(); // 打開session 4 tx = session.beginTransaction(); // 開始一個(gè)事務(wù) 5 User user = (User)session.load(User.class, new Integer("1000")); // 獲取User對象 6 session.delete(user); // 持久化操作 - 刪除 7 tx.commit(); // 提交事務(wù) 8 }catch(HibernateException e){ 9 e.printStackTrace();10 tx.rollback(); // 回滾事務(wù)11 }finally{12 if(null != session){13 session.close(); // 關(guān)閉session14 }15 }
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注