一級緩存
為了獲得更好的性能,NHibernate智能地緩存數據。NHibernate有不同的緩存機制起作用,最重要的就是一級緩存。sess每個ion對象維持一個一級緩存,session對象創建時緩存創建,session對象釋放時緩存銷毀。
緩存只不過是一個哈希表。哈希表根據唯一鍵存儲值,值可以根據唯一鍵檢索。
一個實體由它的ID唯一標識,如果兩個實體類型相同,ID也相等,那么這兩個實體是相等的。NHibernate要求兩個相同類型的對象不能有相同的ID。原因是,如果允許系統有相同ID的兩個實例,那么就會將系統置於不一致的狀態中。有了這個條件,NHibernate就可以執行下面的操作了:
NHibernate session對象從數據庫中加載指定ID的實體,然后放到一級緩存中,訪問該實體的鍵是它的ID值。當系統再次從數據庫中加載同一個實體時,session對象首先檢查它的緩存,如果實體已經存在於緩存中,NHibernate就返回緩存的實例。只有實體不在緩存時,NHibernate session對象才從數據庫中加載實體。看下面的過程:
A步驟:
- 程序請求session ID為1的product
- session問一級緩存:“有ID為1的product嗎?”
- 一級緩存回答說:“沒有”
- session就從數據庫中加載ID為1的product
- session將product放入一級緩存,鍵為product的ID值
- session返回給程序product實例
- 程序執行更多的操作
- 程序再次請求session ID為1的product
- session問一級緩存:“有ID為1的product嗎”
- 一級緩存回答說:“有”
- session就使用ID作為鍵從緩存中加載ID為1的product,並返回給程序
證明:

從上面執行結果可以得出結論:
session.Get<EmployeeInfo>(1);一共獲取數據為a b c d四次,但實際操作數據庫存僅為一次,從而證明了上述的A步驟 正確性:
從第二步可以證明:最重要的就是一級緩存。每個session對象維持一個一級緩存,session對象創建時緩存創建,session對象釋放時緩存銷毀。
二級緩存
我們已經看到NHibernate提供了非常有效的方式緩存數據。可惜,一級緩存綁定到session對象,也就是說每次session被釋放,所有的緩存數據就會丟失。二級緩存定義在session工廠級別的,只要session工廠沒有被釋放緩存就一直存在。一旦實體加載,二級緩存就被激活,實體對所有的session(同session工廠的)都可用。這樣,只要實體在二級緩存中,NHibernate就不會從數據庫加載實體,直到它從緩存中移除。
測試代碼驗證:
1 public static void TextSecondCache() 2 { 3 ISessionFactory sessionFactory = CreateISessionFactoryByXml(); 4 Console.WriteLine("第一個session開始"); 5 using (ISession session = sessionFactory.OpenSession()) 6 { 7 EmployeeInfo a = session.Get<EmployeeInfo>(1); 8 Console.WriteLine("a " + a.EmpName); 9 10 } 11 12 Console.WriteLine("第一個session結束 第2個session開始"); 13 using (ISession session = sessionFactory.OpenSession()) 14 { 15 EmployeeInfo a = session.Get<EmployeeInfo>(1); 16 Console.WriteLine("a " + a.EmpName); 17 } 18 19 }
沒有開啟二級緩存執行情況: 一共執行了二次SQL

開啟二級緩存的情況
第一次執行:只執行了一次SQL操作

第二次執行:沒有執行SQL,直接在SQL中獲取查詢對象

