天天看點

NHibernate之旅(21):探索對象狀态(轉)

本節内容

引入

對象狀态

對象狀态轉換

結語

在程式運作過程中使用對象的方式對資料庫進行操作,這必然會産生一系列的持久化類的執行個體對象。這些對象可能是剛剛建立并準備存儲的,也可能是從資料庫中查詢的,為了區分這些對象,根據對象和目前會話的關聯狀态,我們可以把對象分為三種:

瞬時對象:對象剛剛建立。該對象在資料庫中沒有記錄,也不在ISession緩存中。如果該對象是自動生成主鍵,則該對象的對象辨別符為空。

持久化對象:對象已經通過NHibernate進行了持久化,資料庫中已經存在對應的記錄。如果該對象是自動生成主鍵,則該對象的對象辨別符已被指派。

托管對象:該對象是經過NHibernate儲存過或者從資料庫中取出的,但是與之關聯的ISession已經關閉。雖然它有對象辨別符且資料庫中存在對應記錄,但是已經不再被NHibernate管理。

NHibernate提供了對象狀态管理的功能,支援三種對象狀态:瞬時态(Transient)、持久态(Persistent)、托管态(Detached)。

對象剛剛建立,還沒有來及和ISession關聯的狀态。這時瞬時對象不會被持久化到資料庫中,也不會被賦上辨別符。如果不使用則被GC銷毀。ISession接口可以将其轉換為持久狀态。

這像這樣,剛剛建立了一個Customer對象,是一個瞬時态對象:

剛被儲存的或剛從資料庫中加載的。對象僅在相關聯的ISession生命周期内有效,在資料庫中有相應記錄并有辨別符。對象執行個體由NHibernate架構管理,如果有任何改動,在當然操作送出時,與資料庫同步,即将對象儲存更新到資料庫中。

持久對象關聯的ISession關閉後,這個對象在ISession中脫離了關系,就是托管态了,托管對象仍然有持久對象的所有屬性,對托管對象的引用仍然有效的,我們可以繼續修改它。如果把這個對象重新關聯到ISession上,則再次轉變為持久态,在托管時期的修改會被持久化到資料庫中。

在同步資料庫的情況下執行下面的語句可以轉換對象的狀态。

ISession.Contains(object):檢查ISession中是否包含指定執行個體

重新設定ISession

方法一:ISession.Save():儲存指定執行個體。

方法二:ISession.SaveOrUpdate():配置設定新辨別儲存瞬時态對象。

方法一:ISession.Evict(object):從目前ISession中删除指定執行個體

方法二:ISession.Close():關閉目前ISession

方法一:ISession.Update():更新指定執行個體。

看看這個例子:在托管時期的修改會被持久化到資料庫中;

注意:NHibernate如何知道重新關聯的對象是不是“髒的(修改過的)”?如果是新的ISession,ISession就不能與對象初值來比較這個對象是不是“髒的”,我們在映射檔案中定義<id>元素和<version>元素的unsaved-value屬性,NHibernate就可以自己判斷了。

這個加上一個鎖:如果在托管時期沒有修改,就不執行更新語句,隻轉換為持久态,下面的例子如果在托管時期修改對象,執行更新語句。

方法二:ISession.Merge():合并指定執行個體。不必考慮ISession狀态,ISession中存在相同辨別的持久化對象時,NHibernate便會根據使用者給出的對象狀态覆寫原有的持久化執行個體狀态。

方法三:ISession.SaveOrUpdate():配置設定新辨別儲存瞬時态對象;更新/重新關聯托管态對象。

以上兩個大家自己測試了!

這篇初步知道了對象的狀态。雖然對象的狀态的細節由NHibernate自己維護,但是對象狀态在NHibernate應用中還是比較重要的。同時對象狀态也涉及了NHibernate緩存、離線查詢等内容。

本系列連結:NHibernate之旅系列文章導航