Hibernate持久化對象的狀態

Hibernate持久化對象支持三個對象狀態:
瞬態:當用new關鍵字創建對象時,這個對象還沒有與Hibernate Session關聯,那麼這個對象就可以被認爲是處於瞬態。處於瞬態的對象不會被持久化到數據庫中,也不會被賦予持久化標識。如果這個對象長時間沒有被引用,瞬態對象將被垃圾回收機制銷燬。使用Hibernate Session可以將瞬態對象變爲持久化狀態。
持久化:持久化實例在數據庫中有對應的記錄,並擁有一個持久化的標識(identifier)。持久化的實例可以是剛剛保存的,也可以是剛剛被加載的,無論哪一種,持久化對象都必須與指定的Hibernate Session關聯,沒有與Hibernate Session關聯的對象實例都不能稱爲處於持久化狀態。Hibernate會檢測處於持久化狀態對象的改動 ,在當前操作執行完成時把對象寫入數據庫。開發者不需要手動UPDATE。
脫管:如果一個對象實例曾經處於持久化狀態,但與之關聯的Hibernate Session被關閉,該對象就變成脫管狀態。脫管狀態的對象,依然擁有有效引用,該對象可以繼續被修改。如果脫管對象重新與Hibernate Session關聯,那麼該對象就又變成了持久化狀態,並且在脫管狀態下的改動也不會丟失,可以被寫入數據庫。因爲這個功能,邏輯上的長事務成爲可能,它被稱爲應用程序事務。特性是處於脫管狀態的對象,在改動時無需鎖定數據庫,這樣性能不會降低。
Hibernate 對象狀態演化圖:
這裏寫圖片描述

改變對象爲持久化狀態的方法:
Serializable save(Object obj): 將obj對象變爲持久化狀態,該對象的屬性將被保存到數據庫。
void persist(Object obj): 將obj對象變爲持久化狀態,該對象的屬性將被保存到數據庫。
Serializable save(Object obj,Object pk): 將obj對象保存到數據庫,保存到數據庫時指定主鍵值。
void persist(Object obj,Object pk): 將obj對象轉化爲持久化狀態,保存到數據庫時,指定主鍵值。
save()與persist()方法的區別:使用save()方法保存持久化對象時,該方法返回該持久化對象的標識屬性值(對應記錄的主鍵值);但用persist()保存持久化對象時,該方法沒有任何返回值,因爲save()方法需要立即返回持久化對象的標識屬性值,所以save()方法會立即將持久化對象對應的對象屬性數據插入數據庫。而persist()則保證當它在一個事務外部被調用時,並不立即轉換成insert語句。

Object load(Object.class,Object pk):load()方法用於加載一個持久化實例,這種加載就是根據持久化類的標識屬性值加載持久化實例,也就是從數據庫中根據主鍵值讀取一條記錄。
Object get(Object.class,Object pk …) : get()方法基本與load()方法一樣;
load()與get()的不同:
如果在沒有標識屬性值的記錄,load()方法將可能拋出HibernateException異常,說可能是因爲如果我們在類映射文件中指定了延遲加載,則load()會返回一個未初始化的代理對象,這個代理對象沒有裝載數據記錄,直到程序調用該代理對象的方法時,Hibernate纔會去訪問數據庫;get()雖然也是根據標識屬性值加載持久化實例,但它會立即訪問數據庫,如果沒有對應的記錄,會返回null,而不是代理對象。

load()對持久化實例做的改動在Session flush之前會被自動保存到數據庫,無須程序調用其它方法(不需要調用update方法)來修改持久化。但如果我們調用實例的setter方法改變它的屬性,Hibernate會在Session flush之前生成 一條帶where條件的update語句。
對於一個曾經持久化過的、但已經沒有被Hibernate Session管理的持久化對象,也就是處於脫管狀態的對象,如果要重新持久化,保存修改後的數據,必須用一個新的Hibernate Session來保存。提供的方法有update()、merge()、updateOrSave()。
update()與updateOrSave()方法的區別:
update()是用來保存持久化狀態對象的,但如果不清楚該對象是否曾經持久化過,就可以用updateOrSave()方法,它會自動判斷該對象是否曾經持久化過,曾經持久化過用update()方法,沒有用save()方法。
update()與merge()方法的區別:
update()方法會將參數中的對象持久化,merge()不會,也就是不會受Session管理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章