摘要
上一节对NHibernate二级缓存做了简单介绍,NHibernate二级缓存是由SessionFactory管理的,所有Session共享。这一节介绍二级缓存其他两个方面:二级缓存查询和二级缓存管理。
1. NHibernate二级缓存查询
NHibernate二级缓存查询是指NHibernate将查询记录的集合放到二级缓存中,之后每次查询都可以从二级缓存中拿查询记录信息。
二级缓存使用步骤:
1)在hibernate.cfg.xml文件中,使用cache.use_query_cache定义使用二级缓存查询:<property name="cache.use_query_cache">true</property>
2)在代码中显示地使用IQuery.SetCacheable(true)方法,第一次使用这个方法时,将查询条件和查询结果组成一个字典对象放入二级缓存中,字典的键是查询条件,值是查询结果记录集合。在第二次使用同样查询条件查询时再次调用这个方法,NHibernate直接从二级缓存中读取。如果查询结果记录集合在第一次调用SetCacheable后有变化(添加、修改、删除),则会清空二级缓存中的字典对象,第二次查询从数据库查询。
二级缓存查询有多种定义方式:
1)显示启用缓存查询
只使用IQuery.SetCacheable(true)方法。
程序演示
修改hibernate.cfg.xml文件,添加<property name="cache.use_query_cache">true</property>
<?xml version="1.0" encoding="utf-8" ?> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <session-factory> <property name="connection.connection_string_name">default</property> <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property> <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property> <property name="cache.provider_class">NHibernate.Cache.HashtableCacheProvider</property> <property name="cache.use_second_level_cache">true</property> <property name="cache.use_query_cache">true</property> <mapping assembly="NHibernateDemoApp"/> <class-cache class="NHibernateDemoApp.Customer,NHibernateDemoApp" usage="read-write"/> </session-factory> </hibernate-configuration>
修改Main函数
1 static void Main(string[] args) 2 { 3 HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); 4 5 using (var session = SessionFactory.OpenSession()) 6 { 7 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1") 8 .SetCacheable(true) 9 .List<Customer>(); 10 Console.WriteLine("list count: {0}", customers.Count); 11 } 12 13 using (var session = SessionFactory.OpenSession()) 14 { 15 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1") 16 .SetCacheable(true) 17 .List<Customer>(); 18 Console.WriteLine("list count: {0}", customers.Count); 19 } 20 21 Console.WriteLine("Completed"); 22 Console.ReadLine(); 23 }
打开NHibernateProfile,执行程序,监控结果:
第一次查询后将结果存入二级缓存,第二次查询直接从二级缓存中读取。
2)指定命名缓存区域
在代码中显示调用session.SetCacheRegion方法给二级缓存结果一个强命名。
程序演示
修改Main函数
1 static void Main(string[] args) 2 { 3 HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); 4 5 using (var session = SessionFactory.OpenSession()) 6 { 7 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1") 8 .SetCacheable(true) 9 .SetCacheRegion("customer_chache") 10 .List<Customer>(); 11 Console.WriteLine("list count: {0}", customers.Count); 12 } 13 14 using (var session = SessionFactory.OpenSession()) 15 { 16 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1") 17 .SetCacheable(true) 18 .SetCacheRegion("customer_chache") 19 .List<Customer>(); 20 Console.WriteLine("list count: {0}", customers.Count); 21 } 22 23 Console.WriteLine("Completed"); 24 Console.ReadLine(); 25 }
清空NHibernateProfile监控记录,执行程序,得到结果
3)命名查询
在实体关系映射配置文件hibernate.cfg.xml中,定义二级缓存的命名查询。
<query cacheable="true" cache-mode="normal" name="自定义名称">
Hibernate Query Language查询字符串
</query>
cache-mode一般使用normal(默认方式),从二级缓存中读写。
cache-mode有五个枚举值
- Ignore:不使用二级缓存
- Put:只向二级缓存写数据
- Get:只向二级缓存读数据
- Normal:向二级缓存读和写数据
- Refresh:每次强制刷新二级缓存
程序演示
修改Customer.hbm.xml文件
1 <?xml version="1.0" encoding="utf-8" ?> 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemoApp" namespace="NHibernateDemoApp"> 3 <class name="Customer" table="Customer"> 4 <id name="Id"> 5 <generator class="native"/> 6 </id> 7 <property name="FirstName" not-null="true"/> 8 <property name="LastName" not-null ="true"/> 9 <property name="AverageRating"/> 10 <property name="Points"/> 11 <property name="HasGoldStatus"/> 12 <property name="MemberSince"/> 13 <property name="CreditRating" type="CustomerCreditRating"/> 14 <property name="Street"/> 15 <property name="City"/> 16 <property name="Province"/> 17 <property name="Country"/> 18 </class> 19 <query cacheable="true" cache-mode="normal" name="select_customer"> 20 from Customer 21 </query> 22 </hibernate-mapping>
修改Main函数
1 static void Main(string[] args) 2 { 3 HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); 4 5 using (var session = SessionFactory.OpenSession()) 6 { 7 IList<Customer> customers = session.GetNamedQuery("select_customer") 8 .List<Customer>(); 9 Console.WriteLine("list count: {0}", customers.Count); 10 } 11 12 using (var session = SessionFactory.OpenSession()) 13 { 14 IList<Customer> customers = session.GetNamedQuery("select_customer") 15 .List<Customer>(); 16 Console.WriteLine("list count: {0}", customers.Count); 17 } 18 19 Console.WriteLine("Completed"); 20 Console.ReadLine(); 21 }
清空Profile,执行程序得到结果
2. NHibernate二级缓存管理
NHibernate二级缓存由SessionFactory管理,SessionFactory提供了多个删除二级缓存内容的方法。
- Evict:从二级缓存中删除类实例
- EvictEntity:从二级缓存中删除指定实例
- EvictCollection:从二级缓存中删除集合
- EvictQueries:从二级缓存中删除查询
程序演示
修改Main函数
1 static void Main(string[] args) 2 { 3 HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); 4 5 using (var session = SessionFactory.OpenSession()) 6 { 7 var customer = session.Get<Customer>(1); 8 } 9 SessionFactory.Evict(typeof(Customer)); 10 using (var session = SessionFactory.OpenSession()) 11 { 12 var customer = session.Get<Customer>(1); 13 } 14 15 Console.WriteLine("Completed"); 16 Console.ReadLine(); 17 }
清空NHibernateProfile的Session,执行程序得到结果
也可以强制调用session.SetCacheMode(CacheMode.Refresh),刷新二级缓存内容,第二个session查询时,session重新查询数据库。
程序演示
修改Main函数
1 static void Main(string[] args) 2 { 3 HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); 4 5 using (var session = SessionFactory.OpenSession()) 6 { 7 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1") 8 .SetCacheable(true) 9 .SetCacheRegion("customer_chache") 10 .List<Customer>(); 11 Console.WriteLine("list count: {0}", customers.Count); 12 } 13 14 using (var session = SessionFactory.OpenSession()) 15 { 16 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1") 17 .SetCacheable(true) 18 .SetCacheRegion("customer_chache") 19 .SetCacheMode(CacheMode.Refresh) 20 .List<Customer>(); 21 Console.WriteLine("list count: {0}", customers.Count); 22 } 23 24 Console.WriteLine("Completed"); 25 Console.ReadLine(); 26 }
执行结果,第二次强制查询数据库
作者:丹尼大叔
出处:http://www.cnblogs.com/uncle_danny
本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。