摘要

上一节对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. linux命令:more

    1.命令介绍: more用来逐页输出文件内容,空格键进入到下一页,b键返回到上一页. 2.命令格式: more [选项] 文件 3.命令参数 +n      从笫n行开始显示 -n       定义屏 ...

  2. 使用POSIX正则库匹配一行中多个结果

    正则匹配与正则表达式是什么东西我就不说了,在这里说下POSIX这个c语言正则库在对字符串进行正则匹配时取出多个结果的问题. 首先简单说明下POSIX正则库的几个函数和使用方法 第一个函数:int re ...

  3. day5--<装饰器、模块、字符串格式化、生成器、迭代器>logging模块

    本节大纲: 一:双层装饰器:一个函数可以被多层装饰器进行装饰,函数渲染(编译)从下到上,函数执行从上到下.如下程序: #!/usr/bin/env python #-*-coding:utf-8-*- ...

  4. php-访问数据库

    建一个连接,造一个连接对象 $db = new MySQLi("host","username","passwd","databa ...

  5. windows 下mysql每日定时备份的几种方法

    第一种:新建批处理文件 backup.dat,里面输入以下代码:  代码如下 复制代码 net stop mysql xcopy "C:/Program Files/MySQL/MySQL ...

  6. ADC 电源监测

    我能为别人做点什么?这是我最近在思考的问题. 看了 ADC 电源监测代码,觉得对 ADC 的理解不到位,代码中有很多部分都不懂.如: 1. 为什么初始化的时候管脚设置为输出? 2. ADC 采集到的值 ...

  7. 各种Linux发行版本优缺点对比[转]

    转自:http://www.zzbeidaqingniao.com/linux/20100127/1495.html linux最早由Linus Benedict Torvalds在1991年开始编写 ...

  8. C语言中 *.c和*.h文件的区别!

    C语言中 *.c和*.h文件的区别!  http://blog.163.com/jiaoruijun07@126/blog/static/68943278201042064246409/        ...

  9. nunjucks.js模板渲染

    直接用 script 引入文件: <script src="nunjucks.js"></script> 是使用 render 来直接渲染文件,这种方式支持 ...

  10. 使用pt-stalk分析MySQL的性能波动 (转)

    简介 在MySQL服务器出现短暂(5~30秒)的性能波动的时候,一般的性能监控工具都很难抓住故障现场,也就很难收集对应较细粒度的诊断信息.另外,如果这种波动出现的频率很低,例如几天才一次,我们也很难人 ...