设置缓存

让我们回到 hibernate.cfg.xml 文件中的缓存设置:

<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletEhCacheProvider"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>

注意第一行——它包含缓存引擎类的名称。Hibernate 实际上并没有在内部实现缓存,而是提供了一组接口,您可以使用这些接口实现自己的缓存引擎。

流行的实现包括:

  • EHC缓存
  • 操作系统缓存
  • Swarm缓存
  • JBoss 树缓存

EHC缓存

它可以缓存在内存或磁盘上,也可以缓存在集群缓存中,还支持可选的 Hibernate 查询结果缓存。

操作系统缓存

通过一组丰富的过期策略和查询缓存支持,在同一 JVM 中支持内存和磁盘缓存。

Swarm缓存

基于 JGroups 的集群缓存。它使用集群失效但不支持 Hibernate 查询缓存。

JBoss 缓存

完全事务复制的集群缓存,也基于 JGroups 多播库。它支持复制或失效、同步或异步通信以及乐观和悲观锁定。支持 Hibernate 查询缓存。

这些引擎不支持所有的并行访问策略。实际情况如下表所述:

战略/供应商 只读 非严格读写 读写 事务性的
EHC缓存 X X X
操作系统缓存 X X X
Swarm缓存 X X
JBoss 缓存 X X

EHCache 配置示例

EHCache引擎有自己的配置文件,称为 ehcache.xml。此类文件的大致内容:

<diskStore path="java.io.tmpdir"/>

<defaultCache
    maxElementsInMemory = "1000"
    eternal = "false"
    timeToIdleSeconds = "120"
    timeToLiveSeconds = "120"
    overflowToDisk = "true"
/>

<cache name = "Employee"
    maxElementsInMemory = "500"
    eternal = "true"
    timeToIdleSeconds = "0"
    timeToLiveSeconds = "0"
    overflowToDisk = "false"
/>

在这里,您可以配置一般的缓存设置,也可以单独为每个实体配置缓存设置。在官方文档中阅读更多内容。

缓存统计分析

您可能还需要检查缓存机制的配置情况。Hibernate 专门为此提供了一个特殊的 Statistics 对象。

例子:

Statistics statistics = session.getSessionFactory().getStatistics();
CacheRegionStatistics cacheStatistics = statistics.getDomainRegionStatistics(“com.codegym.employee”);

long hitCount = cacheStatistics.getHitCount();
long missCount = cacheStatistics.getMissCount();
double hitRatio = (double) hitCount / (hitCount + missCount);

我们不会对此进行详细介绍,因为在您用完标准缓存解决方案并需要手动改进它们之前还需要很多年。顺便说一下,这个评论可能是从一个类似的案例中提取出来的:

// Dear programmer:
// When you're done "optimizing" this routine
// and realize how big of a mistake it was to do this,
// please increment the counter at the bottom as a warning
// for the next guy:
// number_of_hours_spent_here = 42