20.3. 管理缓存(Managing the caches)

优质
小牛编辑
132浏览
2023-12-01

无论何时,当你给 save()update()saveOrUpdate() 方法传递一个对象时,或使用 load()get()list()iterate()scroll() 方法获得一个对象时,该对象都将被加入到 Session 的内部缓存中。

当随后 flush() 方法被调用时,对象的状态会和数据库取得同步。如果你不希望此同步操作发生,或者你正处理大量对象、需要对有效管理内存时,你可以调用 evict() 方法,从一级缓存中去掉这些对象及其集合。

ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
while ( cats.next() ) {
    Cat cat = (Cat) cats.get(0);
    doSomethingWithACat(cat);
    sess.evict(cat);
}

Session 还提供了一个 contains() 方法,用来判断某个实例是否处于当前 session 的缓存中。

如若要把所有的对象从 session 缓存中彻底清除,则需要调用 Session.clear()

对于二级缓存来说,在 SessionFactory 中定义了许多方法,清除缓存中实例、整个类、集合实例或者整个集合。

sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class);  //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections

CacheMode 参数用于控制具体的 Session 如何与二级缓存进行交互。

  • CacheMode.NORMAL:从二级缓存中读、写数据。

  • CacheMode.GET:从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。

  • CacheMode.PUT:仅向二级缓存写数据,但不从二级缓存中读数据。

  • CacheMode.REFRESH:仅向二级缓存写数据,但不从二级缓存中读数据。通过 hibernate.cache.use_minimal_puts 的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。

如若需要查看二级缓存或查询缓存区域的内容,你可以使用统计(Statistics) API。

Map cacheEntries = sessionFactory.getStatistics()
        .getSecondLevelCacheStatistics(regionName)
        .getEntries();

此时,你必须手工打开统计选项。可选的,你可以让 Hibernate 更人工可读的方式维护缓存内容。

hibernate.generate_statistics true
hibernate.cache.use_structured_entries true