找回密码
 立即注册
首页 业界区 业界 NHibernate之旅(22):探索NHibernate一级缓存

NHibernate之旅(22):探索NHibernate一级缓存

骆熙华 2025-5-30 01:24:04
本节内容
           
  • 引入       
  • NHibernate一级缓存介绍       
  • NHibernate一级缓存管理       
  • 结语
引入

大家看看上一篇了吗?对象状态。这很容易延伸到NHibernate的缓存。在项目中我们灵活的使用NHibernate的缓存机制。NHibernate性能会大大提高的哦,我们接下来就来探索NHibernate缓存机制吧,这篇我没有准备什么,先来学习下NHibernate一级缓存。
NHibernate一级缓存介绍

NHibernate一级缓存即ISession缓存,ISession缓存属于事务级缓存,是NHibernate内置的。ISession缓存中的数据只在本ISession周期内使用。
ISession实例创建后即可使用ISession缓存。此后,ISession实例操作数据时,首先查询内置缓存,如果ISession缓存中存在相应数据,则直接使用缓存数据。如果不存在,则查询数据库并把其结果存在缓存中。
实例1:查询一次持久化实例
  1. [Test]
  2. public void SessionCacheTest()
  3. {
  4.     Customer customer = _transaction.GetCustomerById(1);
  5. }
复制代码
我们一般就是这样查询一条数据,NHibernate初始化ISession后,ISession缓存中不存在这个数据,这时NHibernate需要从数据库中加载数据。
1.jpeg

实例2:一个会话装载两次持久化实例
  1. [Test]
  2. public void SessionCacheTest2()
  3. {
  4.     Console.WriteLine("第一次读取持久化实例");
  5.     Customer customer1 = _transaction.GetCustomerById(1);
  6.     Console.WriteLine("第二次读取持久化实例");
  7.     Customer customer2 = _transaction.GetCustomerById(1);
  8.     Assert.AreSame(customer1, customer2);
  9. }
复制代码
第一次加载数据后,持久化实例放入缓存。第二次查询同一个持久化实例时,缓存中已经存在该持久化实例,应用程序将直接从缓存中获取数据,而不必再次从数据库中读取数据,这样同时也提高了查询效率,看看结果:
2.jpeg

实例3:分别在两个会话中装载持久化实例
  1. [Test]
  2. public void SessionCacheTest3()
  3. {
  4.     using (_session)
  5.     {
  6.         Console.WriteLine("--Session 1--读取持久化实例");
  7.         Customer customer = _transaction.GetCustomerById(1);
  8.         Assert.IsTrue(_session.Contains(customer));
  9.     }
  10.     ResetSession();
  11.     using (_session)
  12.     {
  13.         Console.WriteLine("--Session 2--读取持久化实例");
  14.         Customer customer = _transaction.GetCustomerById(1);
  15.         Assert.IsTrue(_session.Contains(customer));
  16.     }
  17. }
复制代码
在两个会话中获取同一持久化实例时,两个会话的缓存是独立的,一个会话的数据操作不会影响到另外一个会话。看看输出结果:
3.jpeg

从结果我们可以说明虽然这两个会话读取的是同一个实例,但需要两次数据库操作,从而证明了Session缓存不是共享的,一个Session的缓存内容只有在本Session实例范围内可用。
实例4:比较ISession.Get()和ISession.Load()

不会吧,探索缓存比较这个?呵呵,如果你理解了它们的不同,或许你对NHibernate缓存还有一点了解了。开始。
测试1:使用ISession.Get()方法按标识符获取Customer对象,访问标识符,再访问其它属性。
  1. [Test]
  2. public void GetExistingEntityTest()
  3. {
  4.     Console.WriteLine("----获取持久化实例----");
  5.     Customer customerGet = _session.Get<Customer>(1);
  6.     Assert.IsNotNull(customerGet);
  7.     Console.WriteLine("------访问这个实例的CustomerId属性------");
  8.     Console.WriteLine("这个实例CustomerId属性:{0}", customerGet.CustomerId);
  9.     Assert.AreEqual(customerGet.CustomerId, 1);
  10.     Console.WriteLine("------访问这个实例的FirstName属性(不是CustomerId)-----");
  11.     Console.WriteLine("这个实例的FirstName属性:{0}", customerGet.Name.Firstname);
  12. }
复制代码
直接看结果:
4.jpeg

测试2:使用ISession.Load()方法按标识符获取Customer对象,访问标识符,再访问其它属性。
  1. [Test]
  2. public void LoadExistingEntityTest()
  3. {
  4.     Console.WriteLine("----加载持久化实例----");
  5.     Customer customerLoad = _session.Load<Customer>(1);
  6.     Assert.IsNotNull(customerLoad);
  7.     Console.WriteLine("------访问这个实例的CustomerId属性----");
  8.     Console.WriteLine("这个实例CustomerId属性:{0}", customerLoad.CustomerId);
  9.     Assert.AreEqual(customerLoad.CustomerId, 1);
  10.     Console.WriteLine("------访问这个实例的FirstName属性(不是CustomerId)----");
  11.     Console.WriteLine("这个实例的FirstName属性:{0}", customerLoad.Name.Firstname);
  12. }
复制代码
看看结果:
5.jpeg

看到不同点了吗?这就是区别,我在测试中发现了这个秘密,使用ISession.Get()方法立即把对象实例保存到缓存中,使用ISession.Load()方法当你需要使用的时候再访问数据库把这个实例保存在缓存中。
NHibernate一级缓存管理

NHibernate为我们默认提供了一级缓存,那么我们想显式地去管理ISession缓存,怎么办呢?ISession接口为我们提供了一些方法来显式管理一级缓存。
ISession.Evict(object):从缓存中删除指定实例。
ISession.Clear():清空缓存。
ISession.Contains(object):检查缓存中是否包含指定实例。
实例分析

我们写一个测试来看看如何显式管理吧:
  1. [Test]
  2. public void SessionCacheManageTest()
  3. {
  4.     //1.加载两个实例放入ISession缓存
  5.     Customer customer1 = _transaction.GetCustomerById(1);
  6.     Customer customer2 = _transaction.GetCustomerById(2);
  7.     //2.加载实例后,缓存包含两个实例
  8.     Assert.IsTrue(_session.Contains(customer1));
  9.     Assert.IsTrue(_session.Contains(customer2));
  10.     //3.从缓存中删除Customer1实例
  11.     _session.Evict(customer1);
  12.     Assert.IsFalse(_session.Contains(customer1));
  13.     Assert.IsTrue(_session.Contains(customer2));
  14.     //4.清空ISession缓存,实例不和缓存关联
  15.     _session.Clear();
  16.     Assert.IsFalse(_session.Contains(customer1));
  17.     Assert.IsFalse(_session.Contains(customer2));
  18. }
复制代码
首先,我们加载两个Customer对象,先使用ISession.Evict(object)从缓存中删除一个Customer对象,再使用ISession.Clear()清空缓存,使用Session.Contains(object)检查缓存中的Customer对象。
结语

关于NHibernate一级缓存的内容就这些了,相信你对NHibernate一级缓存有了初步的认识。接下来慢慢探索NHibernate二级缓存吧。
本系列链接:NHibernate之旅系列文章导航
NHibernate Q&A
           
  • 欢迎加入NHibernate中文社区,一起讨论NHibernate知识!       
  • 请到NHibernate中文社区下载本系列相关源码。
下次继续分享NHibernate!

作者:李永京(YJingLee's Blog)
出处:http://lyj.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册