天天看点

[Nhibernate]一级缓存

<a href="http://www.cnblogs.com/wolf-sun/p/4130497.html#t1" target="_blank">写在前面</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4130497.html#t2" target="_blank">文档与系列文章</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4130497.html#t3" target="_blank">一级缓存</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4130497.html#t6" target="_blank">一个例子</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4130497.html#t7" target="_blank">一级缓存管理</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4130497.html#t4" target="_blank">总结</a>

上篇文章介绍了nhibernate中对象的三种状态,通过对象的三种状态,很容易想到缓存。

什麽是缓存?

有时候,某些数据是会经常需要访问的,像硬盘内部的缓存(暂存器的一种)会将读取比较频繁的一些数据存储在缓存中,再次读取时就可以直接从缓存中直接传输。说白了,缓存是用空间换取时间的一种技术。

<a href="http://www.cnblogs.com/wolf-sun/p/3694592.html">[nhibernate]体系结构</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3694901.html">[nhibernate]isessionfactory配置</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3704012.html">[nhibernate]持久化类(persistent classes)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3705229.html">[nhibernate]o/r mapping基础</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3720259.html">[nhibernate]关联映射</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3721528.html">[nhibernate]parent/child</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3724052.html">[nhibernate]缓存(nhibernate.caches)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3734249.html">[nhibernate]nhibernate.tool.hbm2net</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3734313.html">[nhibernate]nullables</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3956802.html">[nhibernate]nhibernate如何映射sqlserver中image字段</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4046672.html">[nhibernate]条件查询criteria query</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4048048.html">[nhibernate]增删改操作</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4049716.html">[nhibernate]事务</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4050714.html">[nhibernate]并发控制</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4067026.html">[nhibernate]组件之依赖对象</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4068749.html">[nhibernate]一对多关系(级联删除,级联添加)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4070935.html">[nhibernate]一对多关系(关联查询)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4074654.html">[nhibernate]多对多关系(关联查询)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4077226.html">[nhibernate]延迟加载</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4082432.html">[nhibernate]立即加载</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4082899.html">[nhibernate]视图处理</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4083402.html">[nhibernate]n+1 select查询问题分析</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4085314.html">[nhibernate]存储过程的使用(一)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4088288.html">[nhibernate]存储过程的使用(二)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4093539.html">[nhibernate]存储过程的使用(三)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4101214.html">[nhibernate]schemaexport工具的使用(一)——通过映射文件修改数据表</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4114870.html">[nhibernate]schemaexport工具的使用(二)——创建表及其约束、存储过程、视图</a>

<a href="http://www.cnblogs.com/wolf-sun/p/4124960.html">[nhibernate]对象状态</a>

nhibernate session有一个内部的(一级)缓存,存放着它的实体。这些缓存没有共享,因此session被销毁时它的缓存也被销毁了。 nhibernate提供了二级缓存系统;它在sessionfactory级别工作。因此它被同一个sessionfactory产生的session共享。 使用每个请求(request)一个session模式,很多session可以并发的访问同一个实体,而不用每次都访问数据库,因此性能获得了提升。

可见一级缓存的过期时间是和session的生命周期相同的。

isession实例创建后即可使用isession缓存。此后,isession实例操作数据时,首先查询内置缓存,如果isession缓存中存在相应数据,则直接使用缓存数据。如果不存在,则查询数据库并把其结果存在缓存中。

为了方便测试,这里改用单元测试的方法进行(也顺便学习一下单元测试,说实话之前很少用这东西,自从使用之后,发现真是太方便了)。

1、根据客户id查询符合条件的客户对象。

[Nhibernate]一级缓存
[Nhibernate]一级缓存

单元测试该方法

[Nhibernate]一级缓存
[Nhibernate]一级缓存

测试结果

[Nhibernate]一级缓存

当第一次加载数据时,缓存中还没有该数据,则从数据库中查询并将查询的结果放入缓存。第二次查询同一个持久化实例时,缓存中已经存在该持久化实例,应用程序将直接从缓存中获取数据,而不必再次从数据库中读取数据,提高了查询效率。

2、分别从两个会话中查询customer

构建测试用例,因为获得isession实例采用的单例模式,如果不进行重置那么session是同一个对象,所以这里需要在第一次查询后重置isession,nhibernatehelper代码如下:

[Nhibernate]一级缓存
[Nhibernate]一级缓存

修改getcustomerbyid方法

[Nhibernate]一级缓存
[Nhibernate]一级缓存

单元测试

[Nhibernate]一级缓存
[Nhibernate]一级缓存

运行测试,结果

[Nhibernate]一级缓存

由上测试可以看出,在两个会话中获取同一持久化实例时,两个会话的缓存是独立的,一个会话的数据操作不会影响到另外一个会话。

从结果我们可以说明虽然这两个会话读取的是同一个实例,但需要至少两次数据库操作(关联的数据表除外),从而说明了session缓存不是共享的,一个session的缓存内容只有在本session实例范围内可用。

3、isession.get()和isession.load()比较

分别使用get和load方法查询某个客户信息。

[Nhibernate]一级缓存
[Nhibernate]一级缓存
[Nhibernate]一级缓存
[Nhibernate]一级缓存

运行单元测试,查看结果

[Nhibernate]一级缓存
[Nhibernate]一级缓存

使用isession.get()方法立即把对象实例保存到缓存中,使用isession.load()方法当你需要使用的时候再访问数据库把这个实例保存在缓存中(有点懒加载的意思,关于lazy加载可参考前面的文章,load方法默认是使用lazy方式加载的)。

isession接口为我们提供了一些常用方法来显式管理一级缓存:

isession.evict(object):从缓存中删除指定实例。

isession.clear():清空缓存。

isession.contains(object):检查缓存中是否包含指定实例。

在customerdata中添加方法

[Nhibernate]一级缓存
[Nhibernate]一级缓存
[Nhibernate]一级缓存
[Nhibernate]一级缓存

单元测试方法

[Nhibernate]一级缓存
[Nhibernate]一级缓存
[Nhibernate]一级缓存

该测试,首先加载两个customer实例,此时已将它们都存入一级缓存,首先使用removecustomerfromcache方法,从缓存中将customer1对象移除,然后使用clearcache方法清空缓存。

本篇文章就到这里,一级缓存是和isession关联的,多个session的缓存是不能共享的。本篇文章使用了单元测试的方式进行测试,也是首次使用单元测试,也稍微研究了一下,关于单元测试的东西,算是附加学习的吧。

参考文章

<a href="http://www.cnblogs.com/lyj/archive/2008/11/24/1340253.html">http://www.cnblogs.com/lyj/archive/2008/11/24/1340253.html</a>

博客地址:

<a href="http://www.cnblogs.com/wolf-sun">http://www.cnblogs.com/wolf-sun/</a>

博客版权:

本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。

如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!

再次感谢您耐心的读完本篇文章。http://www.cnblogs.com/wolf-sun/p/4130497.html