標籤:.com image 共用 個數 方法 教程 target 初步 程式
本節內容
- 引入
- NHibernate一級緩衝介紹
- NHibernate一級緩衝管理
- 結語
引入
大家看看上一篇了嗎?對象狀態。這很容易延伸到NHibernate的緩衝。在項目中我們靈活的使用NHibernate的緩衝機制。NHibernate效能會大大提高的哦,我們接下來就來探索NHibernate緩衝機制吧,這篇我沒有準備什麼,先來學習下NHibernate一級緩衝。
NHibernate一級緩衝介紹
NHibernate一級緩衝即ISession緩衝,ISession緩衝屬於事務級緩衝,是NHibernate內建的。ISession緩衝中的資料只在本ISession周期內使用。
ISession執行個體建立後即可使用ISession緩衝。此後,ISession執行個體操作資料時,首先查詢內建緩衝,如果ISession緩衝中存在相應資料,則直接使用快取資料。如果不存在,則查詢資料庫並把其結果存在緩衝中。
執行個體1:查詢一次持久化執行個體
[Test]public void SessionCacheTest(){ Customer customer = _transaction.GetCustomerById(1);}
我們一般就是這樣查詢一條資料,NHibernate初始化ISession後,ISession緩衝中不存在這個資料,這時NHibernate需要從資料庫中載入資料。
執行個體2:一個會話裝載兩次持久化執行個體
[Test]public void SessionCacheTest2(){ Console.WriteLine("第一次讀取持久化執行個體"); Customer customer1 = _transaction.GetCustomerById(1); Console.WriteLine("第二次讀取持久化執行個體"); Customer customer2 = _transaction.GetCustomerById(1); Assert.AreSame(customer1, customer2);}
第一次載入資料後,持久化執行個體放入緩衝。第二次查詢同一個持久化執行個體時,緩衝中已經存在該持久化執行個體,應用程式將直接從緩衝中擷取資料,而不必再次從資料庫中讀取資料,這樣同時也提高了查詢效率,看看結果:
執行個體3:分別在兩個會話中裝載持久化執行個體
[Test]public void SessionCacheTest3(){ using (_session) { Console.WriteLine("--Session 1--讀取持久化執行個體"); Customer customer = _transaction.GetCustomerById(1); Assert.IsTrue(_session.Contains(customer)); } ResetSession(); using (_session) { Console.WriteLine("--Session 2--讀取持久化執行個體"); Customer customer = _transaction.GetCustomerById(1); Assert.IsTrue(_session.Contains(customer)); }}
在兩個會話中擷取同一持久化執行個體時,兩個會話的緩衝是獨立的,一個會話的資料操作不會影響到另外一個會話。看看輸出結果:
從結果我們可以說明雖然這兩個會話讀取的是同一個執行個體,但需要兩次資料庫操作,從而證明了Session緩衝不是共用的,一個Session的緩衝內容只有在本Session執行個體範圍內可用。
執行個體4:比較ISession.Get()和ISession.Load()
不會吧,探索緩衝比較這個?呵呵,如果你理解了它們的不同,或許你對NHibernate緩衝還有一點瞭解了。開始。
測試1:使用ISession.Get()方法按標識符擷取Customer對象,訪問標識符,再訪問其它屬性。
[Test]public void GetExistingEntityTest(){ Console.WriteLine("----擷取持久化執行個體----"); Customer customerGet = _session.Get<Customer>(1); Assert.IsNotNull(customerGet); Console.WriteLine("------訪問這個執行個體的CustomerId屬性------"); Console.WriteLine("這個執行個體CustomerId屬性:{0}", customerGet.CustomerId); Assert.AreEqual(customerGet.CustomerId, 1); Console.WriteLine("------訪問這個執行個體的FirstName屬性(不是CustomerId)-----"); Console.WriteLine("這個執行個體的FirstName屬性:{0}", customerGet.Name.Firstname);}
直接看結果:
測試2:使用ISession.Load()方法按標識符擷取Customer對象,訪問標識符,再訪問其它屬性。
[Test]public void LoadExistingEntityTest(){ Console.WriteLine("----載入持久化執行個體----"); Customer customerLoad = _session.Load<Customer>(1); Assert.IsNotNull(customerLoad); Console.WriteLine("------訪問這個執行個體的CustomerId屬性----"); Console.WriteLine("這個執行個體CustomerId屬性:{0}", customerLoad.CustomerId); Assert.AreEqual(customerLoad.CustomerId, 1); Console.WriteLine("------訪問這個執行個體的FirstName屬性(不是CustomerId)----"); Console.WriteLine("這個執行個體的FirstName屬性:{0}", customerLoad.Name.Firstname);}
看看結果:
看到不同點了嗎?這就是區別,我在測試中發現了這個秘密,使用ISession.Get()方法立即把對象執行個體儲存到緩衝中,使用ISession.Load()方法當你需要使用的時候再訪問資料庫把這個執行個體儲存在緩衝中。
NHibernate一級緩衝管理
NHibernate為我們預設提供了一級緩衝,那麼我們想顯式地去管理ISession緩衝,怎麼辦呢?ISession介面為我們提供了一些方法來顯式管理一級緩衝。
ISession.Evict(object):從緩衝中刪除指定執行個體。
ISession.Clear():清空緩衝。
ISession.Contains(object):檢查緩衝中是否包含指定執行個體。
執行個體分析
我們寫一個測試來看看如何顯式管理吧:
[Test]public void SessionCacheManageTest(){ //1.載入兩個執行個體放入ISession緩衝 Customer customer1 = _transaction.GetCustomerById(1); Customer customer2 = _transaction.GetCustomerById(2); //2.載入執行個體後,緩衝包含兩個執行個體 Assert.IsTrue(_session.Contains(customer1)); Assert.IsTrue(_session.Contains(customer2)); //3.從緩衝中刪除Customer1執行個體 _session.Evict(customer1); Assert.IsFalse(_session.Contains(customer1)); Assert.IsTrue(_session.Contains(customer2)); //4.清空ISession緩衝,執行個體不和緩衝關聯 _session.Clear(); Assert.IsFalse(_session.Contains(customer1)); Assert.IsFalse(_session.Contains(customer2));}
首先,我們載入兩個Customer對象,先使用ISession.Evict(object)從緩衝中刪除一個Customer對象,再使用ISession.Clear()清空緩衝,使用Session.Contains(object)檢查緩衝中的Customer對象。
結語
關於NHibernate一級緩衝的內容就這些了,相信你對NHibernate一級緩衝有了初步的認識。接下來慢慢探索NHibernate二級緩衝吧。
NHibernate教程(19) —— 一級緩衝