十四、NHibernate之一级缓存

什么是NHibernate一级缓存

NHibernate一级缓存即ISession缓存,ISession缓存属于事务级缓存,是NHibernate内置的。ISession缓存中的数据只在本ISession周期内使用。

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

 

一、一级缓存就在身边

1)       当查询条件相同,且是同一个ISession时由NHibernate自动调用缓存

a)       DAL.Test中编写代码如下:

        [Test]

        public void SessionTest()

        {

            Console.WriteLine("第一次加载");

            Customer customer_1 = session.Get<Customer>(1);

            Console.WriteLine("第二次加载");

            Customer customer_2 = session.Get<Customer>(1);

          }

 

b)       跟踪NHibernate生成SQL的结果

------ Test started: Assembly: DAL.Test.dll ------

 

第一次加载

NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 1

第二次加载

 

1 passed, 0 failed, 0 skipped, took 4.92 seconds (NUnit 2.5.1).

我们可以看到,NHibernate只在第一次加载Customer对象时查询了数据库,而第二次加载时并没有生成相应的SQL语句,这是因为SessionTest()函数中的session在第一次加载后没有被销毁的情况下,对Customer进行第二次加载,那么NHibernate就会先到未被销毁的session中去查询,如果存在则直接从session中返回结果,不存在时,才生成SQL语句并到数据库中查询。

 

2)       这里是同一个ISession,不同的查询条件

a)       为了证明,修改程序如下:

        [Test]

        public void SessionTest()

        {

            Console.WriteLine("第一次加载");

            Customer customer_1 = session.Get<Customer>(1);

            Console.WriteLine("第二次加载");

            Customer customer_2 = session.Get<Customer>(2);

        }

 

b)       跟踪NHibernate生成SQL的结果

------ Test started: Assembly: DAL.Test.dll ------

 

第一次加载

NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 1

第二次加载

NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 2

 

1 passed, 0 failed, 0 skipped, took 5.47 seconds (NUnit 2.5.1).

           这里果然生成了两个SQL语句,因为CustomerId2的对象或者叫结果集在session中不存在,所以必须再到数据库中去查询。

 

3)       这里是同样的查询条件,不同的ISession

a)       为了证明,修改程序如下:

        [Test]

        public void SessionTest()

        {

            using (ISession _session = sessionHelper.GetSession())

            {

                Console.WriteLine("第一次加载");

                Customer customer_1 = _session.Get<Customer>(1);

            }

 

            using (ISession _session = sessionHelper.GetSession())

            {

                Console.WriteLine("第二次加载");

                Customer customer_2 = _session.Get<Customer>(1);

            }

        }

 

b)       跟踪NHibernate生成SQL的结果

------ Test started: Assembly: DAL.Test.dll ------

 

第一次加载

NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 1

第二次加载

NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 1

 

1 passed, 0 failed, 0 skipped, took 4.95 seconds (NUnit 2.5.1).

 

二、ISession.GetISession.Load的区别

1)       ISession.Get

a)       编写代码如下:

        [Test]

        public void SessionTest()

        {

            Console.WriteLine("获取持久化实例:");

            Customer customer = session.Get<Customer>(1);

            Console.WriteLine("访问customer属性:customerId=" + customer.CustomerId);

            Console.WriteLine("访问customer属性:firstName=" + customer.Firstname);

        }

 

b)       结果如下:

------ Test started: Assembly: DAL.Test.dll ------

 

获取持久化实例:

NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 1

访问customer属性:customerId=1

访问customer属性:firstName=luo

 

1 passed, 0 failed, 0 skipped, took 4.92 seconds (NUnit 2.5.1).

 

2)       ISession.Load

a)       修改代码如下:

        [Test]

        public void SessionTest()

        {

            Console.WriteLine("获取持久化实例:");

            Customer customer = session.Load<Customer>(1);

            Console.WriteLine("访问customer属性:customerId=" + customer.CustomerId);

            Console.WriteLine("访问customer属性:firstName=" + customer.Firstname);

        }

 

b)       结果如下:

------ Test started: Assembly: DAL.Test.dll ------

 

获取持久化实例:

访问customer属性:customerId=1

NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 1

访问customer属性:firstName=luo

 

1 passed, 0 failed, 0 skipped, took 5.19 seconds (NUnit 2.5.1).

 

注意:上面两个方法和结果的比较,Get方法一被调用,立即产生SQL语句去查询数据库,而Load方法却是到了需要去取查询结果时才产生SQL去查询数据库,这就是它们两个最大的区别吧!

 

三、一级缓存管理

1)       ISession缓存管理的相关方法

a)       ISession.Evict(object):从缓存中删除指定实例。

b)       ISession.Clear():清空缓存。

c)        ISession.Contains(object):检查缓存中是否包含指定实例。

 

2)       编写代码如下:

        [Test]

        public void SessionTest()

        {

            Customer customer_1, customer_2;

            customer_1 = session.Get<Customer>(1);

            customer_2 = session.Get<Customer>(2);

            Console.WriteLine("customer_1:" + session.Contains(customer_1).ToString());

            Console.WriteLine("customer_2:" + session.Contains(customer_2).ToString() + "/r/n");

 

            session.Evict(customer_1);     //清除某个缓存

            Console.WriteLine("customer_1:" + session.Contains(customer_1).ToString());

            Console.WriteLine("customer_2:" + session.Contains(customer_2).ToString() + "/r/n");

 

            session.Clear();                //清除该ISession中的所有缓存

            Console.WriteLine("customer_1:" + session.Contains(customer_1).ToString());

            Console.WriteLine("customer_2:" + session.Contains(customer_2).ToString() + "/r/n");

        }

 

3)       结果如下:

------ Test started: Assembly: DAL.Test.dll ------

 

NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 1

NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 2

customer_1:True

customer_2:True

 

customer_1:False

customer_2:True

 

customer_1:False

customer_2:True

 

 

1 passed, 0 failed, 0 skipped, took 4.89 seconds (NUnit 2.5.1).

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值