摘要

上一节对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函数

         static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} Console.WriteLine("Completed");
Console.ReadLine();
}

打开NHibernateProfile,执行程序,监控结果:

第一次查询后将结果存入二级缓存,第二次查询直接从二级缓存中读取。

2)指定命名缓存区域

在代码中显示调用session.SetCacheRegion方法给二级缓存结果一个强命名。

程序演示

修改Main函数

         static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.SetCacheRegion("customer_chache")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.SetCacheRegion("customer_chache")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} Console.WriteLine("Completed");
Console.ReadLine();
}

清空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文件

 <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemoApp" namespace="NHibernateDemoApp">
<class name="Customer" table="Customer">
<id name="Id">
<generator class="native"/>
</id>
<property name="FirstName" not-null="true"/>
<property name="LastName" not-null ="true"/>
<property name="AverageRating"/>
<property name="Points"/>
<property name="HasGoldStatus"/>
<property name="MemberSince"/>
<property name="CreditRating" type="CustomerCreditRating"/>
<property name="Street"/>
<property name="City"/>
<property name="Province"/>
<property name="Country"/>
</class>
<query cacheable="true" cache-mode="normal" name="select_customer">
from Customer
</query>
</hibernate-mapping>

修改Main函数

         static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.GetNamedQuery("select_customer")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.GetNamedQuery("select_customer")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} Console.WriteLine("Completed");
Console.ReadLine();
}

清空Profile,执行程序得到结果

2. NHibernate二级缓存管理

NHibernate二级缓存由SessionFactory管理,SessionFactory提供了多个删除二级缓存内容的方法。

  • Evict:从二级缓存中删除类实例
  • EvictEntity:从二级缓存中删除指定实例
  • EvictCollection:从二级缓存中删除集合
  • EvictQueries:从二级缓存中删除查询

程序演示

修改Main函数

         static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
var customer = session.Get<Customer>();
}
SessionFactory.Evict(typeof(Customer));
using (var session = SessionFactory.OpenSession())
{
var customer = session.Get<Customer>();
} Console.WriteLine("Completed");
Console.ReadLine();
}

清空NHibernateProfile的Session,执行程序得到结果

也可以强制调用session.SetCacheMode(CacheMode.Refresh),刷新二级缓存内容,第二个session查询时,session重新查询数据库。

程序演示

修改Main函数

         static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.SetCacheRegion("customer_chache")
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} using (var session = SessionFactory.OpenSession())
{
IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
.SetCacheable(true)
.SetCacheRegion("customer_chache")
.SetCacheMode(CacheMode.Refresh)
.List<Customer>();
Console.WriteLine("list count: {0}", customers.Count);
} Console.WriteLine("Completed");
Console.ReadLine();
}

执行结果,第二次强制查询数据库

NHibernate系列文章十:NHibernate对象二级缓存下的更多相关文章

  1. NHibernate系列文章十八:NHibernate关系之一对多(附程序下载)

    摘要 这篇文章介绍NHibernate最实用的内容:关系映射. NHibernate的关系映射方式有三种: Set:无序对象集合,集合中每一个元素不能重复. List:有序对象集合,集合中的元素可以重 ...

  2. NHibernate系列文章十五:NHibernate组件

    摘要 前面文章介绍了NHibernate对简单.net数据类型的映射对照表.NHibernate也可以映射复杂数据类型,这里介绍通过组件映射NHibernate值对象. 1. NHibernate引用 ...

  3. NHibernate系列文章十六:使用程序集管理NHibernate项目(附程序下载)

    摘要 在实际的项目中,经常是将NHibernate的实体关系映射类做成独立的工程(assembly dll),只对外提供Session调用的接口.这个程序集作为数据访问层,可以被上面的多个工程(ASP ...

  4. NHibernate系列文章十二:Load/Get方法

    摘要 NHibernate提供两个方法按主键值查找对象:Load/Get. 1. Load/Get方法的区别 Load: Load方法可以对查询进行优化. Load方法实际得到一proxy对象,并不立 ...

  5. NHibernate系列文章十四:NHibernate事务

    摘要 NHibernate实现事务机制非常简单,调用ISession.BeginTransaction()开启一个事务对象ITransaction,使用ITransaction.Commit()提交事 ...

  6. NHibernate系列文章十九:NHibernate关系之多对多关系(附程序下载)

    摘要 NHibernate的多对多关系映射由many-to-many定义. 从这里下载本文的代码NHibernate Demo 1.修改数据库 添加Product表 添加ProductOrder表 数 ...

  7. NHibernate系列文章目录

    第一章:NHibernate基础 NHibernate介绍 第一个NHibernate工程 简单的增删改查询 运行时监控 NHibernate配置 数据类型映射 Get/Load方法 NHiberna ...

  8. CRL快速开发框架系列教程十(导出对象结构)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. NHibernate系列文章九:NHibernate对象二级缓存上

    摘要 NHibernate的二级缓存由SessionFactory管理,由所有Session共享. NHibernate缓存读取顺序: 首先从一级缓存中读取,如果一级缓存对象存在,则读取一级缓存对象并 ...

随机推荐

  1. 百度之星热身赛-1001(dfs拓扑排序)

    题意:作为年度优秀魔法学员的奖赏,哈利得到了一台具有魔力的计算机.这台计算机一旦开始处理某个任务,就会一直处理到这个任务结束为止(所以你可以认为它是单线程的).有一天,这台计算机得到了n个任务要处理, ...

  2. 第三个Sprint冲刺第三天

    讨论地点:宿舍 讨论成员:邵家文.李新.朱浩龙.陈俊金 讨论问题:增强了界面的效果,改善了视角

  3. git-quick-start 动画讲解Git命令行

    来源:http://git.oschina.net/wzw/git-quick-start#git-quick-start git-quick-start 这是一个git的快速入门项目,使用一些gif ...

  4. 2016年中国大学生程序设计竞赛(合肥)-重现赛1009 HDU 5969

    最大的位或 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  5. 重写ScrollView 解决ScrollView嵌套viewpager事件冲突

    import android.content.Context; import android.util.AttributeSet; import android.view.GestureDetecto ...

  6. Web存储(Web Storage)的浏览器支持情况

    所有很酷的功能特征的出现最关键的就是浏览器的支持情况,幸运的是,所有的现代浏览器都支持HTML5 Web存储(Web Storage),从IE8开始也支持它.HTML5 Web存储(Web Stora ...

  7. Bean的定义及作用域的注解实现

    1. Classpath扫描与组件管理 从Spring3.0开始,Spring JavaConfig项目提供了很多特性,包括使用java而不是XML定义bean. 比如@configuration, ...

  8. [原创]cocos2d-x研习录-第二阶 基本框架

    了解完Cocos2D-x的基本概念和概念类之后,是不是有一种蠢蠢欲动的冲动,想要探究Cocos2D-x是如何完成这一切的.接着我将通过对Cocos2D-x自代的HelloCpp项目进行分析,初步了解C ...

  9. js 日期按年月日加减

    <script> function isleapyear(year) { if(parseInt(year)%4==0 && parseInt(year)%100!=0)r ...

  10. Jocket

    https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/diagnosTOC.html https://blo ...