本節內容
引入
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二級緩存吧。
出處:http://lyj.cnblogs.com