Hibernate cache

Reprinted: https://www.w3cschool.cn/hibernate/xrvi1iee.html


cache

Caching is about application performance optimization, reducing the frequency of application access to physical data sources, thereby improving application performance.

Caching is also important to Hibernate, which uses a multi-level caching scheme explained below:

image

L1 cache

The first level cache is the Session cache and is a mandatory cache through which all requests must pass . The Session object holds an object in its own right before submitting it to the database.

If you issue multiple updates to an object, Hibernate will try to delay the update as long as possible to reduce the number of SQL update statements issued. If you close the session, all cached objects are lost, either persisted, or updated in the database.

L2 cache

The second-level cache is an optional cache and the first-level cache will always be queried before trying to find an object in the second-level cache. The second level cache can be installed on a per-class and per-collection basis, and is primarily responsible for caching objects across sessions.

Any third-party cache can be used with Hibernate. The org.hibernate.cache.CacheProvider  interface is provided, which must be implemented to provide Hibernate with a cache implementation solution.

Query Hierarchy Cache

Hibernate also implements a query result set cache that is closely integrated with the second level cache.

This is an optional feature and requires two additional physical cache areas that hold the cached query results and the timestamp of when the form was last updated. This is only useful for queries that are run frequently with the same parameter.

second level cache

Hibernate uses the default L1 cache and you don't need to use the L1 cache. Let's look directly at the optional second level cache. Not all classes benefit from caching, so it is important to be able to turn off L2 caching.

Hibernate's second level cache is set up in two steps. First, you must decide which concurrency strategy to use. After that, you use the cache provider to configure the cache expiration time and physical cache properties.

Concurrency strategy

A concurrency strategy is an intermediary that is responsible for keeping data items in the cache and retrieving them from the cache. If you are going to use a second level cache, you must decide which concurrency strategy to use for each persistent class and collection.

  • Transactional: Use this strategy for read-only data, where it is critical for concurrent transactions to prevent stale data in the rare case of an update.
  • Read-write: Use this strategy again for primary read data, in the rare case of an update where concurrent transactions prevent expired data is critical.
  • Nonstrict-read-write: This strategy does not guarantee consistency between cache and database. Use this strategy if the data hardly changes and expired data is not critical.
  • Read-only: A concurrency strategy suitable for never changing data. Use it only for reference data.

If we're going to use a second level cache for our  Employee  class, let's use a read-write strategy to add the mapping element that needs to tell Hibernate to cache Employee instances.

<?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>

The usage="read-write" parameter tells Hibernate to use the read-write concurrency strategy for the defined cache.

cache provider

Your next step after considering the concurrency strategy you will use for your cache candidate class is to pick a cache provider. Hibernate lets you choose a single cache provider for the entire application.

S.N. cache name describe
1 EHCache It can be cached in memory or on disk and clustered, and it supports optional Hibernate query result caching.
2 OSCache 支持在一个单独的 JVM 中缓存到内存和硬盘,同时有丰富的过期策略和查询缓存支持。
3 warmCache 一个基于 JGroups 的聚集缓存。它使用集群失效但是不支持 Hibernate 查询缓存。
4 JBoss Cache 一个也基于 JGroups 多播库的完全事务性的复制集群缓存。它支持复制或者失效,同步或异步通信,乐观和悲观锁定。Hibernate 查询缓存被支持。

每一个缓存提供者都不和每个并发策略兼容。以下的兼容性矩阵将帮助你选择一个合适的组合。

策略/提供者 Read-only Nonstrictread-write Read-write Transactional
EHCache X X X
OSCache X X X
SwarmCache X X
JBoss Cache X X

你将在 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 中。Employee 类的 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 时。

你应该为每个类分析你所有的类并选择合适的缓存策略。有时候,二级缓存可能使应用程序的表现下降。所以首先不允许缓存用基准程序测试你的应用程序,然后开启合适的缓存,之后检测表现是推荐的。如果缓存不提升系统表现那么支持任何类型的缓存都是没有意义的。

查询层次缓存

In order to use the query cache, you must first activate it using the  hibernate.cache.use_query_cache="true"  property in the configuration file. By setting this property to true, you cause Hibernate to create the necessary in-memory caches to hold queries and identifier sets.

Then, to use the query cache, you use the setCacheable(Boolean) method of the Query class. E.g:

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

Hibernate also supports very fine-grained caching support through the concept of cache regions. A cache area is the portion of the cache that is given a name.

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

This code uses methods to tell Hibernate to store and look for queries in the cached employee area.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325519681&siteId=291194637