- 使用Hibernate框架輕松連接數據庫(藍橋杯軟件大賽培訓教材-Java方向)
- 工業和信息化部人才交流中心藍橋杯軟件大賽專家委員會編著
- 1555字
- 2018-12-27 17:47:36
1.7 持久化類狀態
在應用程序中,持久化類的實例可能處于三種的不同狀態,Hibernate注重這三種狀態及其轉換,下面介紹持久化類實例的這三種狀態。
1.7.1 三種狀態
● 瞬時態(Transient)
也稱臨時狀態,該狀態的實例從未與任何持久化上下文(持久化上下文對應于Hibernate中的Session)關聯過,不和數據庫中的數據有任何關聯關系。
● 持久態(Persistent)
持久態實例與某個持久化上下文有關聯,它擁有持久化標識(相當于主鍵值),并且通常在數據庫中有一個對應的行。
● 脫管狀態(Detached)
也稱游離狀態,脫管態實例表示曾經與某個持久化上下文發生過關聯,不過那個上下文被關閉了。它擁有持久化標識,并且在數據庫中通常還存在一個對應的行,只是它已經不在持久化層的管理之下。
1.7.2 三種狀態之間的轉換
對于持久化過程中對象的生命周期,不同的ORM實現使用不同的術語,定義不同的狀態及狀態轉換。這里將繼續使用瞬時、持久、脫管三個術語,介紹對象如何在這三種狀態之間轉換。
如圖1.8所示,可以看到具體的持久管理器(Session)的方法,會觸發對象狀態的變化。在對象生命周期中,可以從瞬時狀態轉換到持久狀態,再轉換到脫管狀態。

圖1.8 Hibernate中的對象狀態及轉換
● 瞬時對象
在Hibernate中,使用new操作符初始化的對象,它們的狀態是瞬時的。也就是說它們沒有跟任何數據庫表的行相關聯,只要應用不再引用這些對象,它們的狀態將會丟失。這時,這些對象的生命期將會終止,變得不可訪問,交給垃圾回收機制來回收。瞬時對象狀態的修改不能在Hibernate的Session中被持久化。
Hibernate認為所有的瞬時對象都是非事務的,所以Hibernate不能對瞬時對象提供任何回滾功能。另外,僅僅被其他瞬時對象引用的對象也是瞬時的。
把對象從瞬時狀態轉換為持久狀態,可以調用Session的save()或saveOrUpdate()方法。
● 持久對象
在Hibernate中,持久對象是具有數據庫標識且在Session中的實例,持久對象有一個主鍵值設為數據庫標識符。持久對象可能來自瞬時對象被save或saveOrUpdate之后形成,也可能是通過get()或load()等方法從數據庫中檢索出來的對象。
持久對象是同Session相關的,是事務的,它們的狀態在事務結束時同數據庫進行同步。當事務提交時,通過執行SQL的INSERT、UPDATE和DELETE語句把內存中持久對象的狀態同步到數據庫中。不過,這個過程也可能在其他時間發生,例如Hibernate在執行查詢之前可能要求同數據庫同步(確保查詢能夠獲得事務早期所做的更改)。通常稱已經分配主鍵值但還沒有插入到數據庫中的持久對象是新的,新的持久對象將會一直保持“新”的狀態直到同步發生。
調用Session的close()和clear()等方法,持久對象脫離Session變成脫管對象,調用Session的delete()方法(數據庫中的對應記錄已被刪除),持久對象變成瞬時對象。
使對象持久化的示例代碼如下:
//省略部分代碼 Session session = sf.openSession(); Seeker seeker = new Seeker(); sesssion.save(seeker); tx.commit( ); session.close( );
● 脫管(游離)對象
在Hibernate中,當事務結束時,同Session相關聯的持久對象仍然存在(如果事務成功,它們在內存中的狀態將會同數據庫同步,在數據庫中通常會有一條記錄對應)。當關閉Session時,這些對象就失去了同Session的關聯,一般把這些對象稱為脫管對象,表明這些對象的狀態不再跟數據庫同步(對它的修改僅發生在內存中),也不再在Hibernate持久化層的管理下。
應用程序通常在事務之外還要使用這些脫管對象,當這些對象重新同Session關聯時,這些對象又變成了持久狀態,例如在事務中調用saveOrUpdate(脫管對象),就會將該脫管對象變成持久對象。
使對象從持久狀態到脫管狀態再到持久狀態的示例代碼如下:
//省略部分代碼 Session sessionOne = sf.openSession(); Seekerseeker=(Seeker)sessionOne.get(Seeker.class,"替換為id"); System.out.println(seeker); sessionOne.close(); //seeker對象成為脫管對象 seeker.setName("zhang"); seeker.setPassword("zhang"); Session sessionTwo = sf.openSession(); sessionTwo.update(seeker); //重新關聯,seeker對象成為持久對象 sessionTwo.beginTransaction().commit(); //seeker的狀態會同步到數據庫 sessionTwo.close();
把持久對象轉換為瞬時對象的示例代碼如下:
//省略部分代碼 Session session = sf.openSession(); Seekerseeker=(Seeker)sessionOne.get(Seeker.class,"替換為id"); session.delete(seeker); session.beginTransaction().commit(); session.close(); //在這里還能使用seeker對象,但它已是瞬時狀態了
點評
在對象三種狀態中,通常最關心的是持久狀態的對象,它的最大特點是:對象處于Session管理范圍,且狀態會同步到數據庫中。另外兩種狀態與之相反,是再普通不過的內存中的對象,不同的是瞬時態的對象沒有數據庫標識,而脫管狀態的對象有數據庫標識。
- 極簡算法史:從數學到機器的故事
- Practical Data Analysis Cookbook
- Python零基礎快樂學習之旅(K12實戰訓練)
- PHP 編程從入門到實踐
- Koa開發:入門、進階與實戰
- PostgreSQL 11從入門到精通(視頻教學版)
- 飛槳PaddlePaddle深度學習實戰
- 自制編程語言
- UI設計全書(全彩)
- Visual Basic程序設計(第三版)
- Oracle 12c從入門到精通(視頻教學超值版)
- Getting Started with hapi.js
- Swift 2 Blueprints
- Oracle Database 12c DBA官方手冊(第8版)
- Learning Google Apps Script