目录

Hibernate - 缓存( Caching)

缓存是一种增强系统性能的机制。 它是应用程序和数据库之间的缓冲区内存。 高速缓存存储器存储最近使用的数据项,以便尽可能地减少数据库命中的数量。

缓存对Hibernate也很重要。 它使用多级缓存方案,如下所述 -

Hibernate缓存

First-level Cache

第一级缓存是会话缓存,是所有请求必须通过的强制缓存。 Session对象在将对象提交到数据库之前将其保持在自己的权限之下。

如果对对象发出多个更新,Hibernate会尽可能地延迟执行更新以减少发出的更新SQL语句的数量。 如果关闭会话,则缓存的所有对象都将丢失,并在数据库中保留或更新。

Second-level Cache

二级缓存是可选缓存,在尝试在二级缓存中定位对象之前,将始终查询第一级缓存。 可以基于每个类和每个集合配置二级缓存,主要负责跨会话缓存对象。

任何第三方缓存都可以与Hibernate一起使用。 提供了一个org.hibernate.cache.CacheProvider接口,必须实现该接口才能为Hibernate提供缓存实现的句柄。

Query-level Cache

Hibernate还为查询结果集实现了一个缓存,它与二级缓存紧密集成。

这是一个可选功能,需要两个额外的物理缓存区域,用于保存缓存的查询结果和上次更新表时的时间戳。 这仅适用于使用相同参数频繁运行的查询。

二级缓存

Hibernate默认使用第一级缓存,而您无需使用第一级缓存。 让我们直接进入可选的二级缓存。 并非所有类都受益于缓存,因此能够禁用二级缓存非常重要。

Hibernate二级缓存分两步设置。 首先,您必须决定使用哪种并发策略。 之后,使用缓存提供程序配置缓存过期和物理缓存属性。

并发策略

并发策略是一个中介,它负责在缓存中存储数据项并从缓存中检索它们。 如果要启用二级缓存,则必须为每个持久化类和集合决定使用哪种缓存并发策略。

  • Transactional - 在极少数更新的情况下,将此策略用于读取主要数据,这对于防止并发事务中的过时数据至关重要。

  • Read-write - 再次将此策略用于读取主要数据,在这种情况下,在极少数情况下更新时,防止并发事务中的陈旧数据至关重要。

  • Nonstrict-read-write - 此策略不保证缓存和数据库之间的一致性。 如果数据几乎没有变化,并且过时数据的可能性很小,则不要使用此策略。

  • Read-only - 适用于数据的并发策略,永远不会更改。 仅用于参考数据。

如果我们要为Employee类使用二级缓存,让我们添加一个映射元素,告诉Hibernate使用读写策略缓存Employee实例。

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      <cache usage = "read-write"/>
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
   </class>
</hibernate-mapping>

usage =“read-write”属性告诉Hibernate对定义的缓存使用读写并发策略。

缓存提供商

在考虑并发策略之后,您将使用缓存候选类来选择缓存提供程序。 Hibernate强制您为整个应用程序选择单个缓存提供程序。

Sr.No. 缓存名称和描述
1

EHCache

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

2

OSCache

支持在单个JVM中缓存到内存和磁盘,并具有丰富的过期策略和查询缓存支持。

3

warmCache

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

4

JBoss Cache

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

每个缓存提供程序都与每个并发策略都不兼容。 以下兼容性矩阵将帮助您选择合适的组合。

战略/供应商 只读 Nonstrictread写 读写 交易
EHCacheXXX
OSCacheXXX
SwarmCacheXX
JBoss Cache XX

您将在hibernate.cfg.xml配置文件中指定缓存提供程序。 我们选择EHCache作为我们的二级缓存提供商 -

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>
      <!-- Assume students is the database name -->
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
      <property name = "hibernate.connection.username">
         root
      </property>
      <property name = "hibernate.connection.password">
         root123
      </property>
      <property name = "hibernate.cache.provider_class">
         org.hibernate.cache.EhCacheProvider
      </property>
      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>
   </session-factory>
</hibernate-configuration>

现在,您需要指定缓存区域的属性。 EHCache有自己的配置文件ehcache.xml ,它应该位于应用程序的CLASSPATH中。 在Employe类的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"
/>

就是这样,现在我们为Employee类和Hibernate启用了二级缓存,现在每当您导航到Employee或按标识符加载Employee时都会访问二级缓存。

您应该分析所有类,并为每个类选择适当的缓存策略。 有时,二级缓存可能会降低应用程序的性能。 因此,建议首先对应用程序进行基准测试,而不启用缓存,然后启用适合的缓存并检查性能。 如果缓存没有提高系统性能,那么启用任何类型的缓存都没有意义。

查询级缓存

要使用查询缓存,必须首先使用配置文件中的hibernate.cache.use_query_cache="true"属性将其激活。 通过将此属性设置为true,可以使Hibernate在内存中创建必要的高速缓存以保存查询和标识符集。

接下来,要使用查询缓存,请使用Query类的setCacheable(Boolean)方法。 例如 -

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

Hibernate还通过缓存区域的概念支持非常细粒度的缓存支持。 缓存区域是给定名称的缓存的一部分。

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

此代码使用该方法告诉Hibernate在缓存的employee区域中存储和查找查询。

↑回到顶部↑
WIKI教程 @2018