首页 > 代码库 > 01-08-03【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之缓存管理

01-08-03【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之缓存管理

http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html

 

管理NHibernate二级缓存

   NHibernate二级缓存由ISessionFactory创建并由ISessionFactory自行维护。我们使用NHibernate操作数据时,ISessionFactory能够自动同步缓存,保证缓存的有效性。但是当我们批量操作数据时,往往NHibernate不能维护缓存持久有效。ISessionFactory提供了可编程方式的缓存管理方法。

 

ISessionFactory提供了一系列的EvictXXX()方法可以方便的从二级缓存中删除一个实例、删除一个集合、一个命名缓存等操作

 

?Evict(persistentClass):从二级缓存中删除persistentClass类所有实例

?Evict(persistentClass, id):从二级缓存中删除指定的持久化实例

?EvictEntity(entityName):从二级缓存中删除命名实例

?EvictCollection(roleName):从二级缓存中删除集合

?EvictCollection(roleName, id):从二级缓存中删除指定的集合

?EvictQueries():从二级缓存中刷新全部查询结果集

?EvictQueries(cacheRegion):从二级缓存中刷新指定查询结果集

ISession内置缓存可以共享ISessionFactory缓存,通过指定ISession的CacheMode可以控制ISession和ISessionFactory的交互方式。ISession可以通过以下五种方式和ISessionFactory交互:

 

?Ignore:更新数据时将二级缓存失效,其它时间不和二级缓存交互

?Put:向二级缓存写数据,但不从二级缓存读数据

?Get:从二级缓存读数据,仅在数据更新时向二级缓存写数据

?Normal:默认方式。从二级缓存读/写数据

?Refresh:向二级缓存写数据,想不从二级缓存读数据,通过在配置文件设置cache.use_minimal_puts从数据库中读取数据时,强制二级缓存刷新

 

测试5:管理NHibernate二级缓存

我们可以使用ISessionFactory提供了一系列的EvictXXX()方法从二级缓存中删除一个实例,看看这个例子在第一次读取持久化实例时,结果集保存在二级缓存中,使用Evict方法从二级缓存中删除所有持久化实例,第二次查询相同数据,二级缓存中不存在则重新从数据库中查询了~~

[Test]

public void SessionFactoryManageTest()

{

    ISessionFactory _sessionFactory = (new Configuration()).Configure().BuildSessionFactory();

    Console.WriteLine("第一次读取持久化实例");

    using (ISession _session = _sessionFactory.OpenSession())

    {

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

        Customer customer2 = _session.Get<Customer>(2);

    }

    Console.WriteLine("从二级缓存中删除Customer类所有实例");



    _sessionFactory.Evict(typeof(Customer));

    //也可以_sessionFactory.EvictEntity("DomainModel.Entities.Customer");



    Console.WriteLine("第二次读取持久化实例");

    using (ISession _session = _sessionFactory.OpenSession())

    {

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

    }

}

 

测试6:强制刷新缓存区域

我们使用ISession提供的.SetCacheMode(CacheMode.Refresh) 方法可以强制刷新缓存区域,这样可以避免数据不一致问题~~

[Test]

public void QueryCacheTest()

{

    using (_session)

    {

        Console.WriteLine("第一次查询某数据,显式缓存查询结果");

        IList<Customer> customers = 

            _session.CreateQuery("from Customer c where c.CustomerId > 2")

            .SetCacheable(true)

            .SetCacheRegion("queryCache")

            .List<Customer>();

        Assert.AreEqual(11, customers.Count);

    }

    ResetSession();

    using (_session)

    {

        Console.WriteLine("第二次查询某数据,显式缓存查询结果");

        Console.WriteLine("----指定特定的命名缓存区域并强制刷新缓存区域----");

        IList<Customer> customers = 

            _session.CreateQuery("from Customer c where c.CustomerId > 2")

            .SetCacheable(true)

            .SetCacheRegion("queryCache")

            .SetCacheMode(CacheMode.Refresh)

            .List<Customer>();

        Assert.AreEqual(11, customers.Count);

    }

}