zoukankan      html  css  js  c++  java
  • NHibernate系列文章八:NHibernate对象一级缓存

    摘要

    Nhibernatea缓存非常强大,按照缓存存储在Session对象还是SessionFactory对象分为一级缓存和二级缓存。

    一级缓存存在于Session对象里,也叫Session缓存,由Session进行管理。一级缓存是NHibernate内置的缓存。

    二级缓存存在于SessionFactory对象里,也叫SessionFactory缓存,由SessionFactory进行管理,并且有大量的第三方dll对他进行扩展,他是一种“可插拔式”的缓存。

    这一节主要讲一级缓存,后面一篇文章介绍二级缓存。

    1. 一级缓存介绍

    NHibernate一级缓存原理:

    • NHibernate的Session对象在自己的内存中开辟”内存池“,这个“内存池”里存储持久化状态的NHibernate实体对象。这个内存池的结构是一个类似于IdentityMap的键值对集合,可以看做是.Net的字典对象。这个“内存池”就是一级缓存。
    • 字典的键就是主键值,字典的值就是持久化对象。如果两个对象的主键值相等,则认为两对象相等。因此,如果映射结构里没有设置主键,NHibernate就无法管理Session的缓存,会报Exception。
    • NHibernate查询从数据库里查询出NHibernate实体对象变成持久化状态,放在Session持久化对象缓存池里,之后访问该对象的时候就自动从缓存里读取。
    • 一个NHibernate持久化状态实体对象只缓存在自己所属的Session里。

    也就是说:

    • 如果同一个Session两次查询同一个NHibernate实体,则第一次查询后将结果存入该session的缓存里,第二次查询使用Session缓存里的记录,只在第一次查询的时候执一次数据库查询。
    • 如果两个Session对象查询同一个NHibernate实体则需要两次查询数据库,执行两次数据库查询。

    2. 程序演示

    1)在同一个session执行两次相同记录的查询

    修改Main函数代码

     1         static void Main(string[] args)
     2         {
     3             HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();
     4 
     5             //在同一个session里执行两次相同记录的查询
     6             using (var session = SessionFactory.OpenSession())
     7             {
     8                 var customer1 = session.Get<Customer>(1);
     9                 var customer2 = session.Get<Customer>(1);
    10             }
    11 
    12             Console.WriteLine("Completed");
    13             Console.ReadLine();
    14         }

    打开NHibernateProfile监控,执行程序,得到结果,看到只执行了一次SQL查询

    2)在不同session中执行两次相同记录的查询

    修改Main函数代码

     1         static void Main(string[] args)
     2         {
     3             HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();
     4 
     5             //在同一个session执行两次相同记录的查询
     6             using (var session = SessionFactory.OpenSession())
     7             {
     8                 var customer = session.Get<Customer>(1);
     9             }
    10 
    11             using (var session = SessionFactory.OpenSession())
    12             {
    13                 var customer = session.Get<Customer>(1);
    14             }
    15 
    16             Console.WriteLine("Completed");
    17             Console.ReadLine();
    18         }

    ctrl+x清空NHibernateProfile监控结果,执行程序,得到结果,执行了两次SQL查询。

    3. 一级缓存补充

    ISession接口为我们提供了一些方法来显式管理一级缓存。

    • ISession.Evict(object):从缓存中删除指定实例
    • ISession.Clear():清空缓存
    • ISession.Contains(object):检查缓存中是否包含指定实例
  • 相关阅读:
    php安全模式笔记
    ./configure,make,make install的作用(转)
    composer自动载入类库的方式
    Specified key was too long; max key length is 1000 bytes
    海量数据中找出前k大数(topk问题)
    斐波那契数列n项的值。(递归和非递归算法Golang实现)
    基于Docker和Golang搭建Web服务器
    Nginx简单介绍以及linux下使用Nginx进行负载均衡的搭建
    php实现商城秒杀
    一致性hash (PHP)
  • 原文地址:https://www.cnblogs.com/uncle_danny/p/5635748.html
Copyright © 2011-2022 走看看