• NHibernate系列文章十:NHibernate对象二级缓存下


    摘要

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

     1         static void Main(string[] args)
     2         {
     3             HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();
     4 
     5             using (var session = SessionFactory.OpenSession())
     6             {
     7                 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
     8                     .SetCacheable(true) 
     9                     .List<Customer>();
    10                 Console.WriteLine("list count: {0}", customers.Count);
    11             }
    12 
    13             using (var session = SessionFactory.OpenSession())
    14             {
    15                 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
    16                     .SetCacheable(true)
    17                     .List<Customer>();
    18                 Console.WriteLine("list count: {0}", customers.Count);
    19             }
    20 
    21             Console.WriteLine("Completed");
    22             Console.ReadLine();
    23         }

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

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

    2)指定命名缓存区域

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

    程序演示

    修改Main函数

     1         static void Main(string[] args)
     2         {
     3             HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();
     4 
     5             using (var session = SessionFactory.OpenSession())
     6             {
     7                 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
     8                     .SetCacheable(true)
     9                     .SetCacheRegion("customer_chache")
    10                     .List<Customer>();
    11                 Console.WriteLine("list count: {0}", customers.Count);
    12             }
    13 
    14             using (var session = SessionFactory.OpenSession())
    15             {
    16                 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
    17                     .SetCacheable(true)
    18                     .SetCacheRegion("customer_chache")
    19                     .List<Customer>();
    20                 Console.WriteLine("list count: {0}", customers.Count);
    21             }
    22 
    23             Console.WriteLine("Completed");
    24             Console.ReadLine();
    25         }

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

     1 <?xml version="1.0" encoding="utf-8" ?>
     2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemoApp" namespace="NHibernateDemoApp">
     3   <class name="Customer" table="Customer">
     4     <id name="Id">
     5       <generator class="native"/>
     6     </id>
     7     <property name="FirstName" not-null="true"/>
     8     <property name="LastName" not-null ="true"/>
     9     <property name="AverageRating"/>
    10     <property name="Points"/>
    11     <property name="HasGoldStatus"/>
    12     <property name="MemberSince"/>
    13     <property name="CreditRating" type="CustomerCreditRating"/>
    14     <property name="Street"/>
    15     <property name="City"/>
    16     <property name="Province"/>
    17     <property name="Country"/>
    18   </class>
    19   <query cacheable="true" cache-mode="normal" name="select_customer">
    20     from Customer
    21   </query>
    22 </hibernate-mapping>

    修改Main函数

     1         static void Main(string[] args)
     2         {
     3             HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();
     4 
     5             using (var session = SessionFactory.OpenSession())
     6             {
     7                 IList<Customer> customers = session.GetNamedQuery("select_customer")
     8                     .List<Customer>();
     9                 Console.WriteLine("list count: {0}", customers.Count);
    10             }
    11 
    12             using (var session = SessionFactory.OpenSession())
    13             {
    14                 IList<Customer> customers = session.GetNamedQuery("select_customer")
    15                     .List<Customer>();
    16                 Console.WriteLine("list count: {0}", customers.Count);
    17             }
    18 
    19             Console.WriteLine("Completed");
    20             Console.ReadLine();
    21         }

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

    2. NHibernate二级缓存管理

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

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

    程序演示

    修改Main函数

     1         static void Main(string[] args)
     2         {
     3             HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();
     4 
     5             using (var session = SessionFactory.OpenSession())
     6             {
     7                 var customer = session.Get<Customer>(1);
     8             }
     9             SessionFactory.Evict(typeof(Customer));
    10             using (var session = SessionFactory.OpenSession())
    11             {
    12                 var customer = session.Get<Customer>(1);
    13             }
    14 
    15             Console.WriteLine("Completed");
    16             Console.ReadLine();
    17         }

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

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

    程序演示

    修改Main函数

     1         static void Main(string[] args)
     2         {
     3             HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();
     4 
     5             using (var session = SessionFactory.OpenSession())
     6             {
     7                 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
     8                      .SetCacheable(true)
     9                      .SetCacheRegion("customer_chache")
    10                     .List<Customer>();
    11                 Console.WriteLine("list count: {0}", customers.Count);
    12             }
    13             
    14             using (var session = SessionFactory.OpenSession())
    15             {
    16                 IList<Customer> customers = session.CreateQuery("from Customer c where c.Id > 1")
    17                      .SetCacheable(true)
    18                      .SetCacheRegion("customer_chache")
    19                      .SetCacheMode(CacheMode.Refresh)
    20                     .List<Customer>();
    21                 Console.WriteLine("list count: {0}", customers.Count);
    22             }
    23 
    24             Console.WriteLine("Completed");
    25             Console.ReadLine();
    26         }

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

  • 相关阅读:
    TreeView拖动
    反射机制
    SQLServer2005/2008 XML数据类型操作
    开发与研发:一字之差的感想
    设置在64位机器上的IIS(IIS6/IIS7)兼容32位程序(64位ODBC和32位ODBC的问题同样适用)
    setTimeout和setInterval的使用
    Oracle 安装/使用、配置/卸载
    链接sql数据库以及Oracle 数据库和启动缓存以及停止缓存
    jQuery学习笔记—— .html(),.text()和.val()的使用
    C# List<T>用法
  • 原文地址:https://www.cnblogs.com/uncle_danny/p/5638039.html
Copyright © 2020-2023  润新知