Hibernate採用低侵入式的設計,它對持久化類幾乎不做任何要求。也就是說hibernate操作的持久化類基本都是普通java對象。對於持久化類的要求這裡不做說明。只就持久化對象的狀態和各個狀態之間的轉換。
Hibernate持久化對象有如下幾種狀態:
1、瞬態:對象有new操作符建立,但是並沒與Hibernate Session關聯。處於瞬態的對象是不會被持久化到資料庫中的。如果程式中失去了瞬態對象的引用,瞬態對象就會被記憶體回收機制銷毀。
2、持久化:持久化實力在資料庫中有對應的記錄,並且擁有一個持久化標識。對於持久化對象,它必須要與指定的Hibernate Session關聯起來。
3、託管:該對象曾經處於持久化裝填,但隨著與之關聯的Session被關閉了,那麼該對象也就變為了託管狀態。
是hibernate持久化執行個體的狀態演化圖:
1、瞬態轉變為持久化狀態
當我們通過new建立一個執行個體時,這個執行個體就處於瞬態。瞬態可以通過以下幾個方法轉換為持久化狀態。
save(Object obj):將對象變為持久化狀態,該對象的屬性將被儲存到資料庫中。
persist(Object obj):將對象變為持久化狀態,該對象的屬性將被儲存到資料庫中
save(Object obj,Object pk):將對象儲存到資料庫,儲存到資料庫時,指定主索引值
persist(Object obj,Object pk):將對象儲存到資料庫,儲存到資料庫時,指定主索引值
如果對象的識別屬性是generated類型的,那麼hibernate將會在執行save()方法時自動產生識別屬性值,並且將該識別屬性值分配給該對象,並且識別屬性值會在sava()被調用時自動產生並分配給該對象。如果對象的識別屬性是assigned類型的,或者是複合主鍵,那麼該識別屬性值應該在調用save()方法之前手動賦予給該對象。
在使用save()和persist()方法的時候,有一個區別:使用save()方法儲存持久化對象時,該方法返回持久化對象的識別屬性值。但是persist不會返回任何值。
2、載入持久化執行個體
我們可以使用load()方法來載入一個持久化執行個體,這種載入時根據持久化類的識別屬性值載入持久化執行個體的,其實質就是根據主鍵從資料表中載入一條新的紀錄。
1 News new = seesion.load(News.class,new integer(PK));
同時也可以使用get()方法載入一個持久化執行個體。它和load方法的相同點在於兩者都是根據主鍵裝載持久化執行個體的。不同就在於get()會立即訪問資料庫,而laod()會消極式載入,不會立即訪問資料庫。
一旦載入了該持久化執行個體後,該執行個體就會處於持久化狀態,這是如果對該持久化執行個體所做的修改將會保持到資料庫中。
如:
1 new.setTitle("11111111");
這段代碼會在session.flush之前自動保持到資料庫中。也就是說,修改對象最簡單的方法就是在Session處於開啟狀態時載入它,然後只見修改即可。
如下:
1 New n = seesion.load(News.class,new Integer(PK));2 n.setTitlte("新標題");3 Session.flush();
2、託管
當一個對象處於脫管的狀態後,程式應該使用新的session來儲存這些修改。hibernate提供了update()、merge()和updateOrSace()等方法來儲存這些修改。
如下:
1 News news = firstSession.load(News.class,new Integer(pk));2 //第一個session關閉3 firstSession.close();4 //修改脫管狀態下的持久化對象5 n.setTitle("新標題");6 //開啟第二個session7 Session secondeSession = sf.openSession();8 //儲存脫管對象所做的修改9 secondeSession.update(n);
當我們用另一個session來儲存這種修改後,該脫管對象會再次回到持久化狀態。
當需要使用update來儲存程式對持久化對象所在的修改時,如果不清楚該對象是否曾經持久化過,那麼可以選擇updateOrSave()方法,該方法會自動判斷該對象是否曾經持久化過,如果持久化過,則使用update()來操作,否是使用save()方法。