菜鳥學SSH(八)——Hibernate物件的三種狀態

劉水鏡發表於2014-02-11

前面寫了幾篇關於SSH的部落格,但不是Struts就是Spring,Hibernate還從來沒寫過呢。說好是SSH的,怎麼可以光寫那兩個,而不寫Hibernate呢對吧。今天就先說說Hibernate物件的三種狀態,Hibernate物件有三種狀態,分別是:臨時態(Transient)、 持久態(Persistent)、遊離態(Detached)。


臨時狀態:是指從物件通過new語句建立到被持久化之前的狀態,此時物件不在Session的快取中。


處在此狀態的物件具備以下特點:

1,不在Session快取中,不與任何Session例項相關聯。

2,在資料庫中沒有與之對應的記錄。


通常在下列情況下物件會進入臨時狀態:

1,通過new語句建立新物件。

2,執行delete()方法,對於遊離狀態的物件,delete()方法會將其與資料庫中對應的記錄刪除;而對於持久化狀態的物件,delete()方法會將其與資料庫中對應的記錄刪除,並將其在Session快取中刪除。


例如:Object object = new Object();

此時object為臨時狀態,資料庫中沒有對應的資料,Session快取中也沒有相關聯的例項。


持久化狀態:是指物件被持久化到Session物件被銷燬之前的狀態,此時物件在Session的快取中。


處在此狀態的物件具備以下特點:

1,在Session快取中,與Session例項相關聯。

2,在資料庫中有與之對應的記錄。

3,Session在清理快取的時候,會根據持久化物件的屬性變化更新資料庫。


通常在下列情況下物件會進入臨時狀態:

1,執行save()或saveOrUpdate()方法,使臨時物件轉變為持久化物件。

2,執行upda()或saveOrUpdate()方法,使遊離物件轉變為持久化物件。

3,執行load()或get()方法,返回的物件都是持久化物件。

4,執行find()方法,返回List集合中存放的都是持久化物件。

5,在允許級聯儲存的情況下,Session在清理快取時會把與持久化物件關聯的臨時物件轉變為持久化物件。


例如:Session session = factory.openSession();  object.setName("持久化物件"); session.save(object);

此時object物件為持久化物件,Session快取中有相關聯的例項,資料庫中有相應的記錄。


遊離狀態:是指從持久化物件的Session物件被銷燬到該物件消失之前的狀態,此時物件不在Session的快取中。


處在此狀態的物件具備以下特點:

1,不在Session快取中,不與任何Session例項相關聯。

2,在資料庫中有與之對應的記錄(前提是沒有其他Session例項刪除該條記錄)。


通常在下列情況下物件會進入臨時狀態:

1,執行close()方法,將Session快取清空,快取中的所有持久化物件將轉變成遊離物件。

2,執行evict()方法,能從快取中刪除一個持久化物件,使之轉變成遊離物件。


例如:session.close(); 

此時上文的object物件為遊離物件,Session快取中沒有有相關聯的例項,資料庫中有相應的記錄。


三種狀態之間的轉換過程


對上圖的解析:

1,當一個物件被new了以後此物件處於臨時態(Transient)。

2,然後對此物件執行session的save() 或者saveOrUpdate()方法後,此物件被放入session的一級快取進入持久態。

2,當再對此物件執行evict()/close()/clear()的操作後此物件進入遊離態(Detached)。

4,遊離態(Detached)和臨時態(Transient)的物件由於沒有被session管理會在適當的時機被java的垃圾回收站(garbage)回收。

5,執行session的get()/load()/find()/iternte()等方法從資料庫裡查詢的到的物件,處於持久態(Persistent)。

6,當對資料庫中的紀錄進行update()/saveOrUpdate()/lock()操作後遊離態的物件就過渡到持久態。

7,處於持久態(Persistent)與遊離態(Detached)的物件在資料庫中都有對應的記錄。

8,臨時態(Transient)與遊離態(Detached)的物件都可以被回收可是臨時態的物件在資料庫中沒有對應的紀錄,而遊離態的物件在資料庫中有對用的紀錄。


三種狀態在程式的轉換過程:


程式碼

物件的生命週期狀態

物件的狀態

Object object = new Object();

開始生命週期

開始生命週期

Session session = factory.openSession(); 
Transaction tx = session.beginTransaction(); 

在生命週期中

臨時狀態

session.save(object);

在生命週期中

轉變為持久化狀態

tx.commit();

在生命週期中

持久化狀態

session.close(); 

在生命週期中

轉變為遊離狀態

System.out.println(object.getName()); 

在生命週期中

遊離狀態

object = null;

結束生命週期

結束生命週期

 

三種狀態裡面,只有持久化狀態在Session快取中有相關聯的例項,臨時狀態跟遊離狀態都沒有。臨時狀態資料庫裡沒有對應的記錄,其他兩種可能又記錄,也可能沒有記錄。

好了,Hibernate物件的三種狀態就說到這裡,接下來可能跟大家說說Hibernate的Session,期待不?





相關文章