本節内容
引入
對象狀态
對象狀态轉換
結語
在程式運作過程中使用對象的方式對資料庫進行操作,這必然會産生一系列的持久化類的執行個體對象。這些對象可能是剛剛建立并準備存儲的,也可能是從資料庫中查詢的,為了區分這些對象,根據對象和目前會話的關聯狀态,我們可以把對象分為三種:
瞬時對象:對象剛剛建立。該對象在資料庫中沒有記錄,也不在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之旅系列文章導航