十四、NHibernate之一级缓存

什么是NHibernate一级缓存NHibernate一级缓存即ISession缓存,ISession缓存属于事务级缓存,是NHibernate内置的。ISession缓存中的数据只在本ISession周期内使用。ISession实例创建后即可使用ISession缓存。此后,ISession实例操作数据时,首先查询内置缓存,如果ISession缓存中存在相应数据,则直接使用缓存数据。如果不存在,则查询数据库并把其结果存在缓存中。 一、一级缓存就在身边1) 当查询条件相同,且是同一个ISession时由NHibernate自动调用缓存a) 在DAL.Test中编写代码如下: [Test] public void { 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 { 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语句,因为CustomerId为2的对象或者叫结果集在session中不存在,所以必须再到数据库中去查询。 3) 这里是同样的查询条件,不同的ISessiona) 为了证明,修改程序如下: [Test] public void { using (ISession { Console.WriteLine(“第一次加载”); Customer customer_1 = _session.Get<Customer>(1); } using (ISession { 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.Get和ISession.Load的区别?1) ISession.Geta) 编写代码如下: [Test] public void { 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 { 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=1NHibernate: 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 { Customer customer_1 = session.Get<Customer>(1); customer_2 = session.Get<Customer>(2); Console.WriteLine(“customer_1:” Console.WriteLine(“customer_2:” + session.Contains(customer_2).ToString() + “/r/n”); session.Evict(customer_1); //清除某个缓存 Console.WriteLine(“customer_1:” Console.WriteLine(“customer_2:” + session.Contains(customer_2).ToString() + “/r/n”); session.Clear(); //清除该ISession中的所有缓存 Console.WriteLine(“customer_1:” 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 = 1NHibernate: SELECT customer0_.CustomerId as CustomerId4_0_, customer0_.Firstname as Firstname4_0_, customer0_.Lastname as Lastname4_0_ FROM Customer customer0_ WHERE customer0_.CustomerId=@p0;@p0 = 2customer_1:Truecustomer_2:True customer_1:Falsecustomer_2:True customer_1:Falsecustomer_2:True 1 passed, 0 failed, 0 skipped, took 4.89 seconds (NUnit 2.5.1). 做事的能力往往只能给你一种机会,

十四、NHibernate之一级缓存

相关文章:

你感兴趣的文章:

标签云: