1. 程式人生 > 實用技巧 >NHibernate之(22):探索NHibernate一級快取

NHibernate之(22):探索NHibernate一級快取

本節內容

  • 引入
  • 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之旅系列文章導航

NHibernate Q&A

下次繼續分享NHibernate!


作者:李永京(YJingLee's Blog)
出處:http://lyj.cnblogs.com
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。