使用:
先添加hibernate-ehcache jar包
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>SOME-HIBERNATE-VERSION</version>
</dependency>
在EntityManagerFactory中添加属性:
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">/your-cache-config.xml</prop>
your-cache-config.xml文件:
<?xml version="1.0" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
updateCheck="false"
xsi:noNamespaceSchemaLocation="ehcache.xsd" name="yourCacheManager">
<diskStore path="java.io.tmpdir"/>
<cache name="yourEntityCache"
maxEntriesLocalHeap="10000"
eternal="false"
overflowToDisk="false"
timeToLiveSeconds="86400" />
<cache name="org.hibernate.cache.internal.StandardQueryCache"
maxElementsInMemory="10000"
eternal="false
timeToLiveSeconds="86400"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU" />
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToLiveSeconds="86400"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU" />
</ehcache>
代码中配置:@org.hibernate.annotations.Cache
@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY,
region="yourEntityCache")
public class SomeEntity {
...
}
级联的对象cache
@Entity
public class SomeEntity {
@OneToMany
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY,
region="yourCollectionRegion")
private Set<OtherEntity> other;
}
查询cache
@NamedQuery(name="account.queryName",
query="select acct from Account ...",
hints={
@QueryHint(name="org.hibernate.cacheable",
value="true")
}
})
Criteria 使用
List cats = session.createCriteria(Cat.class)
.setCacheable(true)
.list();
工作原理:
二级缓存:
存储结构类似:
*-----------------------------------------*
| Person Data Cache |
|-----------------------------------------|
| 1 -> [ "John" , "Q" , "Public" , null ] |
| 2 -> [ "Joey" , "D" , "Public" , 1 ] |
| 3 -> [ "Sara" , "N" , "Public" , 1 ] |
*-----------------------------------------*
存储的key是entity的id,通过EntityManager.find()方法来找到对象
查询缓存:
结构类似:
*----------------------------------------------------------*
| Query Cache |
|----------------------------------------------------------|
| ["from Person where firstName=?", ["Joey"] ] -> [1, 2] ] |
*----------------------------------------------------------*
并且存储的是一组match 查询的ID
查询时,通过query查询先找到id,然后通过id到二级缓存中寻找,如果找不到再到db中查询
二级缓存及查询缓存的缺点:
1. 影响性能的地方
比如查询缓存中返回一组id,这一组id在二级缓存中找不到对应的记录的话,将会一次次根据id查询对象
2. 继承的影响
@Inheritance
那么子类的@Cache都不起作用,只有父类的@Cache才起作用
@Entity @Inheritance @Cache(CacheConcurrencyStrategy.READ_ONLY) public class BaseEntity { ... } @Entity @Cache(CacheConcurrencyStrategy.READ_WRITE) public class SomeReadWriteEntity extends BaseEntity { ... } @Entity @Cache(CacheConcurrencyStrategy.TRANSACTIONAL) public class SomeTransactionalEntity extends BaseEntity { ... }
这里的SomeReadWriteEntity和SomeTransactionalEntity 都是 READ_ONLY的
引用原文: http://www.javacodegeeks.com/2014/06/pitfalls-of-the-hibernate-second-level-query-caches.html