01-08-02【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider...

 

 

第一步骤:hibernate.cfg.xml文件补上如下配置:

<?xml version="1.0" encoding="utf-8"?>
<!-- 
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it 
for your own use before compile tests in VisualStudio.
-->
<!-- This is the System.Data.dll provider for SQL Server -->
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
    <session-factory name="NHibernate.Test123456">
        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
        <property name="connection.connection_string">

      <!--用于测试自动生成数据库表(不自动生成数据库)-->
      <!--<property name="hbm2ddl.auto">update</property>-->
      Server=(local);initial catalog=NHibernateSampleAutoCreateTable;Integrated Security=SSPI

      <!--Server=(local);initial catalog=NHibernateSample;Integrated Security=SSPI-->
    </property>
        <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>

    <!--输出所有的SQL语句到控制台,一般开发打开这个-->
    <property name="show_sql">true</property>
    <!--整齐的SQL输出到控制台-->
    <property name="format_sql">true</property>
    <!--自动生成数据库表(不自动生成数据库)-->
    <property name="hbm2ddl.auto">update</property>
    <!--在数据表设计中如果采用了 bit 类型的字段,并且对应了业务类中类型为 bool 值,一定要如上设置下-->
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    
     <!--=======加入Nhibernate自身的HashtabeCache的二级缓存配置=============================-->
    <!--1.配置二级缓存提供程序-->
    <property name="cache.provider_class">NHibernate.Cache.HashtableCacheProvider</property>
    <!--2.显式启用二级缓存-->
    <property name ="cache.use_second_level_cache">true</property>
    <!--4.启动查询缓存-->
    <property name="cache.use_query_cache">true</property>

    <!--实体类所在的程序集-->
    <mapping assembly="Model"/>
     <!--3.配置映射的二级缓存-->
    <class-cache class="Model.Customer,Model" usage="read-write"/>
    <!--<collection-cache collection ="集合名称" region="默认集合名称"
                      usage="read-write"/>-->

    </session-factory>
</hibernate-configuration>

 

实体类上也可以配二级缓存策略,如:

Customer.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
                   namespace="Model" 
                   assembly="Model" 
                    default-lazy="true">
  
  <class name="Model.Customer, Model"
         table="Customer"
         discriminator-value="0" lazy="false">
    <!--1.这个不是必须的,因为在nhibernate.cfg.xml文件中已经有了一个总配置
        2.cache标签必须在id标签前面
    -->
    <cache usage="read-write"/>
    <!--unsaved-value="0" 主键表中不需要定义,而是需要在子表中定义-->
    <id name="CustomerId"
        column="CustomerId"
        type="int" 
        unsaved-value="0">
      <generator class="native" />
      <!-- unsaved-value used to be null and generator was increment in h2.0.3 -->
    </id>
。。。。。。。。。。。。。。。
    <set name="Orders" table="Order"  lazy="true"
         generic="true"
          inverse="false" cascade="all">
      <!--二级缓存策略-->
      <cache usage="read-write"/>
      <key column="CustomerId" foreign-key="FK_CustomerOrders"/> 
      <one-to-many class="Model.Order,Model"/>
    </set>
  </class>
</hibernate-mapping>

 

测试1:

       二级缓存与Get方法+Lazy设置的关系:

测试图解:


 
 

 

经测试,得出如下结论:

 

Get方法+Lazy配置+二级缓存测试结果:

                                         Customer.hbm.xml的<Set name="Orders"        Customer.hbm.xml的<Set name="Orders"       

                                                          lazy="true">                   lazy="false">      

                                                         <cache usage="read-write"/>                      <cache usage="read-write"/>

 

Customer数据库中Order个数等于零                   Get方法从二级缓存获取Customer                               Get方法从二级缓存获取Customer 

Customer数据库中Order个数大于零                   Get方法从二级缓存获取Customer                               Get方法从不从二级缓存获取Customer 

 

 

 

------------------------更新二级缓存测试---------------------------------------------------------------

测试更新-1:

前置条件:

1.Customer没Orders

2.

  <class name="Model.Customer, Model"
         table="Customer"
         discriminator-value="0" lazy="true">
    <!--1.这个不是必须的,因为在nhibernate.cfg.xml文件中已经有了一个总配置
        2.cache标签必须在id标签前面
    -->
    <cache usage="read-write"/>

测试代码:

 

        [TestMethod]
        public void TestSessionFactoryCacheUpdateCustomerHavingNotOrders()
        {
            CustomerService customerService = new CustomerService();

            Customer customer = new Customer()
            {
                FirstName = "Test",
                LastName = "TestSessionFactoryCache",
                Age = 10
            };

            customerService.Add(customer);
            int customerId = customer.CustomerId;


            Console.WriteLine("第1次获取数据并且更新------------------------------:");
            Customer customerGet1 = customerService.Get(customerId);

            Console.WriteLine("更新前:Id:{0}-->FirtstName:{1}"
                , customerGet1.CustomerId, customerGet1.FirstName);

            customerGet1.FirstName = "我是更新后的FirstName"; //修改FirstName
            customerService.Update(customerGet1);  //保存更新得到数据库。

            Console.WriteLine("更新后:Id:{0}-->FirtstName:{1}"
                , customerGet1.CustomerId, customerGet1.FirstName);

            Console.WriteLine("第2次获取数据==============================:");
            Customer customerGet2 = customerService.Get(customerId);
            Console.WriteLine("Id:{0}-->FirtstName:{1}"
                , customerGet2.CustomerId, customerGet2.FirstName);

            Console.WriteLine("第3次获取数据==============================:");
            Customer customerGet3 = customerService.Get(customerId);
            Console.WriteLine("Id:{0}-->FirtstName:{1}"
                , customerGet3.CustomerId, customerGet3.FirstName);

        }
View Code

 

测试结果:

NHibernate: 
    INSERT 
    INTO
        Customer
        (Version, Firstname, Lastname, Age) 
    VALUES
        (@p0, @p1, @p2, @p3);
    select
        SCOPE_IDENTITY();
    @p0 = 1 [Type: Int32 (0)],
    @p1 = 'Test' [Type: String (4000)],
    @p2 = 'TestSessionFactoryCache' [Type: String (4000)],
    @p3 = 10 [Type: Int32 (0)]
第1次获取数据并且更新------------------------------:
NHibernate: 
    SELECT
        customer0_.CustomerId as CustomerId0_0_,
        customer0_.Version as Version0_0_,
        customer0_.Firstname as Firstname0_0_,
        customer0_.Lastname as Lastname0_0_,
        customer0_.Age as Age0_0_ 
    FROM
        Customer customer0_ 
    WHERE
        customer0_.CustomerId=@p0;
    @p0 = 198 [Type: Int32 (0)]
NHibernate: 
    SELECT
        orders0_.CustomerId as CustomerId1_,
        orders0_.OrderId as OrderId1_,
        orders0_.OrderId as OrderId1_0_,
        orders0_.Version as Version1_0_,
        orders0_.OrderDate as OrderDate1_0_,
        orders0_.CustomerId as CustomerId1_0_ 
    FROM
        [
    Order] orders0_ WHERE
        orders0_.CustomerId=@p0;
    @p0 = 198 [Type: Int32 (0)]
更新前:Id:198-->FirtstName:Test
NHibernate: 
    UPDATE
        Customer 
    SET
        Version = @p0,
        Firstname = @p1,
        Lastname = @p2,
        Age = @p3 
    WHERE
        CustomerId = @p4 
        AND Version = @p5;
    @p0 = 2 [Type: Int32 (0)], @p1 = '我是更新后的FirstName' [Type: String (4000)], @p2 = 'TestSessionFactoryCache' [Type: String (4000)], @p3 = 10 [Type: Int32 (0)], @p4 = 198 [Type: Int32 (0)], @p5 = 1 [Type: Int32 (0)]
更新后:Id:198-->FirtstName:我是更新后的FirstName
第2次获取数据==============================:
Id:198-->FirtstName:我是更新后的FirstName
第3次获取数据==============================:
Id:198-->FirtstName:我是更新后的FirstName
View Code

 

 

---------------------------------------------------

测试更新-2

前置条件:

1.Customer有Orders

2.

    <set name="Orders" table="Order"  lazy="false"
         generic="true"
          inverse="false" cascade="all">
      <!--二级缓存策略-->
      <cache usage="read-write"/>
      <key column="CustomerId" foreign-key="FK_CustomerOrders"/> 
      <one-to-many class="Model.Order,Model"/>
    </set>

 

测试代码和结果:表明2级缓存失效

        [TestMethod]
        public void TestSessionFactoryCacheUpdateCustomerHavingOrders()
        {
            CustomerService customerService = new CustomerService();

            Customer customer = new Customer()
            {
                FirstName = "Test",
                LastName = "TestSessionFactoryCache",
                Age = 10
            };

            Order order1 = new Order()
            {
                OrderDate = DateTime.Now,
                Customer = customer
            };
            customer.Orders.Add(order1);

            customerService.Add(customer);
            int customerId = customer.CustomerId;


            Console.WriteLine("第1次获取数据并且更新------------------------------:");
            Customer customerGet1 = customerService.Get(customerId);

            Console.WriteLine("更新前:Id:{0}-->FirtstName:{1}"
                , customerGet1.CustomerId, customerGet1.FirstName);

            customerGet1.FirstName = "我是更新后的FirstName"; //修改FirstName
            customerService.Update(customerGet1);  //保存更新得到数据库。

            Console.WriteLine("更新后:Id:{0}-->FirtstName:{1}"
                , customerGet1.CustomerId, customerGet1.FirstName);

            Console.WriteLine("第2次获取数据==============================:");
            Customer customerGet2 = customerService.Get(customerId);
            Console.WriteLine("Id:{0}-->FirtstName:{1}"
                , customerGet2.CustomerId, customerGet2.FirstName);

            Console.WriteLine("第3次获取数据==============================:");
            Customer customerGet3 = customerService.Get(customerId);
            Console.WriteLine("Id:{0}-->FirtstName:{1}"
                , customerGet3.CustomerId, customerGet3.FirstName);

        }
View Code
NHibernate: 
    INSERT 
    INTO
        Customer
        (Version, Firstname, Lastname, Age) 
    VALUES
        (@p0, @p1, @p2, @p3);
    select
        SCOPE_IDENTITY();
    @p0 = 1 [Type: Int32 (0)],
    @p1 = 'Test' [Type: String (4000)],
    @p2 = 'TestSessionFactoryCache' [Type: String (4000)],
    @p3 = 10 [Type: Int32 (0)]
NHibernate: 
    INSERT 
    INTO
        [
        
    Order] (
        Version, OrderDate, CustomerId
    ) 
VALUES
    (@p0, @p1, @p2);
    select
        SCOPE_IDENTITY();
    @p0 = 1 [Type: Int32 (0)],
    @p1 = 2014/5/29 23:15:57 [Type: DateTime (0)],
    @p2 = 199 [Type: Int32 (0)]
第1次获取数据并且更新------------------------------:
NHibernate: 
    SELECT
        customer0_.CustomerId as CustomerId0_0_,
        customer0_.Version as Version0_0_,
        customer0_.Firstname as Firstname0_0_,
        customer0_.Lastname as Lastname0_0_,
        customer0_.Age as Age0_0_ 
    FROM
        Customer customer0_ 
    WHERE
        customer0_.CustomerId=@p0;
    @p0 = 199 [Type: Int32 (0)]
NHibernate: 
    SELECT
        orders0_.CustomerId as CustomerId1_,
        orders0_.OrderId as OrderId1_,
        orders0_.OrderId as OrderId1_0_,
        orders0_.Version as Version1_0_,
        orders0_.OrderDate as OrderDate1_0_,
        orders0_.CustomerId as CustomerId1_0_ 
    FROM
        [
    Order] orders0_ WHERE
        orders0_.CustomerId=@p0;
    @p0 = 199 [Type: Int32 (0)]
更新前:Id:199-->FirtstName:Test
NHibernate: 
    UPDATE
        Customer 
    SET
        Version = @p0,
        Firstname = @p1,
        Lastname = @p2,
        Age = @p3 
    WHERE
        CustomerId = @p4 
        AND Version = @p5;
    @p0 = 2 [Type: Int32 (0)], @p1 = '我是更新后的FirstName' [Type: String (4000)], @p2 = 'TestSessionFactoryCache' [Type: String (4000)], @p3 = 10 [Type: Int32 (0)], @p4 = 199 [Type: Int32 (0)], @p5 = 1 [Type: Int32 (0)]
NHibernate: 
    UPDATE
        [
    Order] SET
        Version = @p0,
        OrderDate = @p1,
        CustomerId = @p2 
    WHERE
        OrderId = @p3 
        AND Version = @p4;
    @p0 = 2 [Type: Int32 (0)], @p1 = 2014/5/29 23:15:57 [Type: DateTime (0)], @p2 = 199 [Type: Int32 (0)], @p3 = 34 [Type: Int32 (0)], @p4 = 1 [Type: Int32 (0)]
更新后:Id:199-->FirtstName:我是更新后的FirstName
第2次获取数据==============================:
NHibernate: 
    SELECT
        order0_.OrderId as OrderId1_0_,
        order0_.Version as Version1_0_,
        order0_.OrderDate as OrderDate1_0_,
        order0_.CustomerId as CustomerId1_0_ 
    FROM
        [
    Order] order0_ WHERE
        order0_.OrderId=@p0;
    @p0 = 34 [Type: Int32 (0)]
Id:199-->FirtstName:我是更新后的FirstName
第3次获取数据==============================:
NHibernate: 
    SELECT
        order0_.OrderId as OrderId1_0_,
        order0_.Version as Version1_0_,
        order0_.OrderDate as OrderDate1_0_,
        order0_.CustomerId as CustomerId1_0_ 
    FROM
        [
    Order] order0_ WHERE
        order0_.OrderId=@p0;
    @p0 = 34 [Type: Int32 (0)]
Id:199-->FirtstName:我是更新后的FirstName
View Code

 

将该测试(测试更新-2)的前置条件2改为:

lazy="true"  ,即修改后的配置如下:  
    <set name="Orders" table="Order"  lazy="true"
         generic="true"
          inverse="false" cascade="all">
      <!--二级缓存策略-->
      <cache usage="read-write"/>
      <key column="CustomerId" foreign-key="FK_CustomerOrders"/> 
      <one-to-many class="Model.Order,Model"/>
    </set>

 

lazy="true" 时,2级缓存生效,测试结果如下所示:
NHibernate: 
    INSERT 
    INTO
        Customer
        (Version, Firstname, Lastname, Age) 
    VALUES
        (@p0, @p1, @p2, @p3);
    select
        SCOPE_IDENTITY();
    @p0 = 1 [Type: Int32 (0)],
    @p1 = 'Test' [Type: String (4000)],
    @p2 = 'TestSessionFactoryCache' [Type: String (4000)],
    @p3 = 10 [Type: Int32 (0)]
NHibernate: 
    INSERT 
    INTO
        [
        
    Order] (
        Version, OrderDate, CustomerId
    ) 
VALUES
    (@p0, @p1, @p2);
    select
        SCOPE_IDENTITY();
    @p0 = 1 [Type: Int32 (0)],
    @p1 = 2014/5/29 22:55:43 [Type: DateTime (0)],
    @p2 = 193 [Type: Int32 (0)]
第1次获取数据并且更新------------------------------:
NHibernate: 
    SELECT
        customer0_.CustomerId as CustomerId0_0_,
        customer0_.Version as Version0_0_,
        customer0_.Firstname as Firstname0_0_,
        customer0_.Lastname as Lastname0_0_,
        customer0_.Age as Age0_0_ 
    FROM
        Customer customer0_ 
    WHERE
        customer0_.CustomerId=@p0;
    @p0 = 193 [Type: Int32 (0)]
更新前:Id:193-->FirtstName:Test
NHibernate: 
    UPDATE
        Customer 
    SET
        Version = @p0,
        Firstname = @p1,
        Lastname = @p2,
        Age = @p3 
    WHERE
        CustomerId = @p4 
        AND Version = @p5;
    @p0 = 2 [Type: Int32 (0)], @p1 = '我是更新后的FirstName' [Type: String (4000)], @p2 = 'TestSessionFactoryCache' [Type: String (4000)], @p3 = 10 [Type: Int32 (0)], @p4 = 193 [Type: Int32 (0)], @p5 = 1 [Type: Int32 (0)]
更新后:Id:193-->FirtstName:我是更新后的FirstName
第2次获取数据==============================:
Id:193-->FirtstName:我是更新后的FirstName
第3次获取数据==============================:
Id:193-->FirtstName:我是更新后的FirstName
View Code

 

经测试,得出如下结论:

 

Update方法+Get方法+Lazy配置+二级缓存测试结果:

                                         Customer.hbm.xml的<Set name="Orders"                 Customer.hbm.xml的<Set name="Orders"       

                                                          lazy="true">                   lazy="false">      

                                                         <cache usage="read-write"/>                      <cache usage="read-write"/>

 ----------------------------------------------------------------------------------------------------------------------------------------

Customer数据库中Order个数等于零                 用 Update方法Customer后,                           用 Update方法Customer后,

                                                                Get方法从二级缓存获取Customer                     Get方法从二级缓存获取Customer 

-----------------------------------------------------------------------------------------------------------------------------------------                           

Customer数据库中Order个数大于零                   用 Update方法Customer后                              用 Update方法Customer后

                                Get方法从二级缓存获取Customer                        Get方法从不从二级缓存获取Customer  

 

 

-----------------------------------------------------------------------------------------------------------------------------------------

 

 

转载于:https://www.cnblogs.com/easy5weikai/p/3759277.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值