NHibernate中的Clear和Flush方法
在NHibernata中,提供了l缓存机制。Clear和Flush都是针对session缓存(一级缓存)中的数据。无论还是load()还是get(),都是先查询缓存(一级缓存),没有再查询数据库。如下代码,执行了同一个id的2次查询,但是执行了一次sql的查询。
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 TplCustomer model = session.Get(typeof(TplCustomer),150218) as TplCustomer; 4 Console.WriteLine(model.LastName); 5 var model_1 = session.Get<TplCustomer>(150218); 6 Console.WriteLine(model_1.LastName); 7 rs.Commit(); 8 session.Close(); 9 Console.ReadLine(); 10 }
虽然查询了2次,但是执行了一次sql,如图:
- session.Clear():调用Clear方法,可以强制清除Session缓存。如下代码,调用了Clear()之后,查询了2次id相同的数据,缺执行了2次sql语句。
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 TplCustomer model = session.Get(typeof(TplCustomer),150218) as TplCustomer; 4 Console.WriteLine(model.LastName); 5 session.Clear(); 6 var model_1 = session.Get<TplCustomer>(150218); 7 Console.WriteLine(model_1.LastName); 8 rs.Commit(); 9 session.Close(); 10 Console.ReadLine(); 11 }
执行了2次sql语句:
-
- session.Flush():调用Flush方法,可以强制与数据库同步。如下代码,更新2次数据值,只执行了一次update代码。
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 TplCustomer model = session.Get(typeof(TplCustomer),150218) as TplCustomer; 4 model.LastName = "KingTao";
6 model.LastName = "KingHk"; 7 8 session.Update(model); 9 rs.Commit(); 10 session.Close(); 11 Console.ReadLine(); 12 }
- session.Flush():调用Flush方法,可以强制与数据库同步。如下代码,更新2次数据值,只执行了一次update代码。
调用Flush(),强制更新数据,更新了2次:
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 TplCustomer model = session.Get(typeof(TplCustomer),150218) as TplCustomer; 4 model.LastName = "KingTao"; 5 session.Flush(); 6 model.LastName = "KingHkp"; 7 8 session.Update(model); 9 rs.Commit(); 10 session.Close(); 11 Console.ReadLine(); 12 }
flush()同步了数据库,但不会提交事务。commit()方法执行前,会先执行flush(),然后提交事务。提交事务意味着对数据库所做的更新被永久保存下来。通常,执行session,save,update,delete的时候,只是一个登记行为。只要调用Flush方法之后,NHiberrnate才会将缓存中的数据提交的数据库。(将登记行为的sql提交到数据库,但是还没有提交数据,只有提交事务之后,才会向数据库中提交数据,永久保存到数据库。)
- FlushMode可以设置FlushMode.Always|AUTO|COMMIT|NEVER|MANUAL
- Always:任何代码都会Flush
- AUTO:默认方式–自动
- Commit:COMMIT时
- Never:始终不
- MANUAL:手动方式
- 备忘
- NHibernate支持2个级别的缓存,默认只支持一级缓存(session缓存)
- 每个Session内部自带一个一级缓存,Session关闭时,对应的一级缓存自动清除
- save、update 、saveOrupdate、load、get,、list、iterate、lock都会向缓存中存对象
- 可以从缓存中读取数据的只有:get、load、iterate
- query对象默认不读取缓存,如果要使其支持缓存,则需要使用如下语法:query.setCacheable(true)。例代码:
using (ITransaction rs = session.BeginTransaction())
{
var model = session.CreateQuery("from TplCustomer where SeqId=:ps")
.SetParameter("ps", 150218).List<TplCustomer>();
Console.WriteLine(model.FirstOrDefault().LastName);
var _model = session.CreateQuery("from TplCustomer where SeqId=:ps")
.SetParameter("ps", 150218).List<TplCustomer>();
Console.WriteLine(_model.FirstOrDefault().LastName);
session.Close();
Console.ReadLine();
}
使用query.setCacheable(true),查询缓存,只有查询条件和原来查询完全相同时,才会在缓存中匹配成功:
1 using (ITransaction rs = session.BeginTransaction()) 2 { 3 var model = session.CreateQuery("from TplCustomer h where h.SeqId=150218") 4 .SetCacheable(true).List<TplCustomer>(); 5 Console.WriteLine(model.FirstOrDefault().LastName); 6 7 var _model = session.CreateQuery("from TplCustomer h where h.SeqId=150218") 8 .SetCacheable(true).List<TplCustomer>(); 9 Console.WriteLine(_model.FirstOrDefault().LastName); 10 session.Close(); 11 Console.ReadLine(); 12 }
6.如果主键使用“native”生成,则不放入二级缓存.不需要事务提交,就直接保存到数据库中了。
7.NHibernate中的一级缓存,是个字典值。字典的key就是主键值。如果key值相同,则认为是同一个对象。如果映射结构里没有配置主键值,NHibernate就无法管理session的缓存,就会报异常。
8.一个持久对象,只存储在自己所属的session里面。