前面寫了幾篇關於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(); |
在生命週期中 |
臨時狀態 |
session.save(object); |
在生命週期中 |
轉變為持久化狀態 |
tx.commit(); |
在生命週期中 |
持久化狀態 |
session.close(); |
在生命週期中 |
轉變為遊離狀態 |
System.out.println(object.getName()); |
在生命週期中 |
遊離狀態 |
object = null; |
結束生命週期 |
結束生命週期 |
三種狀態裡面,只有持久化狀態在Session快取中有相關聯的例項,臨時狀態跟遊離狀態都沒有。臨時狀態資料庫裡沒有對應的記錄,其他兩種可能又記錄,也可能沒有記錄。
好了,Hibernate物件的三種狀態就說到這裡,接下來可能跟大家說說Hibernate的Session,期待不?