NHibernate中的Clear和Flush方法

Posted 一生安然

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

   调用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
  1. Always:任何代码都会Flush
  2. AUTO:默认方式–自动
  3. Commit:COMMIT时
  4. Never:始终不
  5. MANUAL:手动方式
  • 备忘
  1. NHibernate支持2个级别的缓存,默认只支持一级缓存(session缓存)
  2. 每个Session内部自带一个一级缓存,Session关闭时,对应的一级缓存自动清除
  3. save、update 、saveOrupdate、load、get,、list、iterate、lock都会向缓存中存对象
  4. 可以从缓存中读取数据的只有:get、load、iterate
  5. 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里面。

以上是关于NHibernate中的Clear和Flush方法的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate ISession Flush:何时何地使用它,为啥?

Hibernate强制清除Session缓存 Clear与Flush方法 FlushMode设置

Hibernate中一级缓存概念以及flush与clear的区别

Hibernate缓存的evictclear和flush方法

04-JSP 内置对象

io中需要flush()刷新的流