返回

十四、NHibernate之一级缓存

发布时间:2022-12-10 09:43:41 315
# 数据库# 数据
什么是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(1);
Console.WriteLine("第二次加载");
Customer customer_2 = session.Get(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(1);
Console.WriteLine("第二次加载");
Customer customer_2 = session.Get(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) 这里是同样的查询条件,不同的ISession
a) 为了证明,修改程序如下:
[Test]
public void
{
using (ISession
{
Console.WriteLine("第一次加载");
Customer customer_1 = _session.Get(1);
}

using (ISession
{
Console.WriteLine("第二次加载");
Customer customer_2 = _session.Get(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.Get
a) 编写代码如下:
[Test]
public void
{
Console.WriteLine("获取持久化实例:");
Customer customer = session.Get(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(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
{
Customer
customer_1 = session.Get(1);
customer_2 = session.Get(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 = 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)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
JQuery UI之(二)对话框——dialog 2022-12-10 09:12:07