1、首先设置EhCache,建立配置文件ehcache.xml,默认的位置在class-path,可以放到你的src目录下:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"<!-- 缓存最大数目 -->
eternal="false"<!-- 缓存是否持久 -->
overflowToDisk="true"<!-- 是否保存到磁盘,当系统当机时-->
timeToIdleSeconds="300"<!-- 当缓存闲置n秒后销毁 -->
timeToLiveSeconds="180"<!-- 当缓存存活n秒后销毁-->
diskPersistent="false"
diskExpiryThreadIntervalSeconds= "120"/>
</ehcache>
2、在Hibernate配置文件中设置:
<!-- 设置Hibernate的缓存接口类,这个类在Hibernate包中 -->
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- 是否使用查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
如果使用spring调用Hibernate的sessionFactory的话,这样设置:
<!--HibernateSession工厂管理 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="datasource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
<property name="mappingDirectoryLocations">
<list>
<value>/WEB-INF/classes/cn/rmic/manager/hibernate/</value>
</list>
</property>
</bean>
说明一下:如果不设置“查询缓存”,那么hibernate只会缓存使用load()方法获得的单个持久化对象,如果想缓存使用findall()、
list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话,就需要设置
hibernate.cache.use_query_cache true 才行
3、在Hbm文件中添加<cache usage="read-only"/>
4、如果需要“查询缓存”,还需要在使用Query或Criteria()时设置其setCacheable(true);属性
5、实践出真知,给一段测试程序,如果成功的话第二次查询时不会读取数据库
package cn.rmic.hibernatesample;
import java.util.List;
import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import cn.rmic.hibernatesample.hibernate.HibernateSessionFactory;
import cn.rmic.manager.po.Resources;
public class testCacheSelectList ...{
public static void main(String[] args) ...{
Session s=HibernateSessionFactory.getSession();
Criteria c=s.createCriteria(Resources.class);
c.setCacheable(true);
List l=c.list();
Resources resources=(Resources)l.get(0);
System.out.println("-1-"+resources.getName());
HibernateSessionFactory.closeSession();
try ...{
Thread.sleep(5000);
} catch (InterruptedException e) ...{
// TODO Auto-generated catch block
e.printStackTrace();
}
s=HibernateSessionFactory.getSession();
c=s.createCriteria(Resources.class);
c.setCacheable(true);
l=c.list();
resources=(Resources)l.get(0);
System.out.println("-2-"+resources.getName());
HibernateSessionFactory.closeSession();
}
}
1. 在Hibernate配置文件中设置:
<!--
Hibernate SessionFactory
-->
<
bean id
=
"
sessionFactory
"
class
=
"
org.springframework.orm.hibernate3.LocalSessionFactoryBean
"
>
<
property name
=
"
dataSource
"
ref
=
"
dataSource
"
/>
<
property name
=
"
mappingResources
"
>
<
list
>
<
value
>
com
/
ouou
/
model
/
Videos.hbm.xml
</
value
>
</
list
>
</
property
>
<
property name
=
"
hibernateProperties
"
>
<
props
>
<
prop key
=
"
hibernate.dialect
"
>
org.hibernate.dialect.MySQLDialect
</
prop
>
<
prop key
=
"
hibernate.current_session_context_class
"
>
thread
</
prop
>
<
prop key
=
"
hibernate.cglib.use_reflection_optimizer
"
>
false
</
prop
>
<
prop key
=
"
hibernate.query.substitutions
"
>
true
'
Y
'
,
false
'
N
'
</
prop
>
<!--
add ehcache
-->
<
prop key
=
"
hibernate.cache.provider_class
"
>
org.hibernate.cache.EhCacheProvider
</
prop
>
<
prop key
=
"
hibernate.cache.use_query_cache
"
>
false
</
prop
><!--
是否使用查询缓存
-->
<!--
<
prop key
=
"
hibernate.cache.provider_configuration_file_resource_path
"
>/
ehcache.xml
</
prop
>
<
prop key
=
"
hibernate.show_sql
"
>
true
</
prop
>
-->
<!--<
prop key
=
"
hibernate.transaction.auto_close_session
"
>
true
</
prop
>-->
<
prop key
=
"
connection.provider_class
"
>
org.hibernate.connection.C3P0ConnectionProvider
</
prop
>
<!--
Create
/
update the database tables automatically when the JVM starts up
<
prop key
=
"
hibernate.hbm2ddl.auto
"
>
update
</
prop
>
-->
<!--
Turn batching off
for
better error messages under PostgreSQL
-->
<
prop key
=
"
hibernate.jdbc.batch_size
"
>
25
</
prop
>
<!--
<
prop key
=
"
hibernate.connection.pool_size
"
>
10
</
prop
>
-->
</
props
>
</
property
>
</
bean
>
如果不设置“查询缓存”,那么hibernate只会缓存使用load()方法获得的单个持久化对象,如果想缓存使用findall()、
list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话,就需要设置
hibernate.cache.use_query_cache true 才行
2.首先设置EhCache,建立配置文件ehcache.xml,默认的位置在class-path,可以放到你的src目录下:
<
ehcache
>
<!--
Sets the path to the directory where cache .data files are created.
If the path is a Java System Property it is replaced by
its value in the running VM.
The following properties are translated:
user.home
-
User
'
s home directory
user.dir
-
User
'
s current working directory
java.io.tmpdir
-
Default temp file path
-->
<!--<
diskStore path
=
"
java.io.tmpdir
"
/>-->
<
diskStore path
=
"
/data/ehcache
"
/>
<!--
Default Cache configuration. These will applied to caches programmatically created through
the CacheManager.
The following attributes are required:
maxElementsInMemory
-
Sets the maximum number of objects that will be created in memory
eternal
-
Sets whether elements are eternal. If eternal, timeouts are
ignored and the element is never expired.
overflowToDisk
-
Sets whether elements can overflow to disk when the in
-
memory cache
has reached the maxInMemory limit.
The following attributes are optional:
timeToIdleSeconds
-
Sets the time to idle
for
an element before it expires.
i.e. The maximum amount of time between accesses before an
element expires Is only used
if
the element is not eternal.
Optional attribute. A value of
0
means that an Element can idle
for
infinity.The
default
value is
0
.
timeToLiveSeconds
-
Sets the time to live
for
an element before it expires.
i.e. The maximum time between creation time and when an element
expires. Is only used
if
the element is not eternal.
Optional attribute. A value of
0
means that and Element can live
for
infinity.
The
default
value is
0
.
diskPersistent
-
Whether the disk store persists between restarts of the Virtual
Machine.
The
default
value is
false
.
diskExpiryThreadIntervalSeconds
-
The number of seconds between runs of the disk expiry thread.
The
default
value is
120
seconds.
-->
<
defaultCache
maxElementsInMemory
=
"
10000
"
eternal
=
"
false
"
overflowToDisk
=
"
true
"
timeToIdleSeconds
=
"
120
"
timeToLiveSeconds
=
"
120
"
diskPersistent
=
"
false
"
diskExpiryThreadIntervalSeconds
=
"
120
"
/>
<
cache name
=
"
org.hibernate.cache.UpdateTimestampsCache
"
maxElementsInMemory
=
"
5000
"
eternal
=
"
true
"
overflowToDisk
=
"
true
"
/>
<
cache name
=
"
org.hibernate.cache.StandardQueryCache
"
maxElementsInMemory
=
"
5
"
eternal
=
"
false
"
timeToLiveSeconds
=
"
120
"
overflowToDisk
=
"
true
"
/>
<
cache name
=
"
userCache
"
maxElementsInMemory
=
"
100000
"
eternal
=
"
false
"
timeToIdleSeconds
=
"
600
"
timeToLiveSeconds
=
"
600
"
overflowToDisk
=
"
false
"
diskPersistent
=
"
false
"
/>
<
cache name
=
"
com.ouou.webapp.util.OuouMethodIntecepter
"
maxElementsInMemory
=
"
100000
"
eternal
=
"
false
"
timeToIdleSeconds
=
"
600
"
timeToLiveSeconds
=
"
600
"
overflowToDisk
=
"
false
"
diskPersistent
=
"
false
"
/>
<
cache name
=
"
bbcode
"
maxElementsInMemory
=
"
100000
"
eternal
=
"
false
"
timeToIdleSeconds
=
"
600
"
timeToLiveSeconds
=
"
600
"
overflowToDisk
=
"
false
"
diskPersistent
=
"
false
"
/>
<
cache name
=
"
com.ouou.model.Videos
"
maxElementsInMemory
=
"
10000
"
eternal
=
"
false
"
overflowToDisk
=
"
false
"
timeToIdleSeconds
=
"
120
"
timeToLiveSeconds
=
"
120
"
diskPersistent
=
"
false
"
/>
<
cache name
=
"
com.ouou.model.Tags
"
maxElementsInMemory
=
"
10000
"
eternal
=
"
false
"
overflowToDisk
=
"
false
"
timeToIdleSeconds
=
"
120
"
timeToLiveSeconds
=
"
120
"
diskPersistent
=
"
false
"
/>
</
ehcache
>
以com.ouou.model.Videos为例子
在Videos.hbm.xml中配置:
<class name="Videos" table="TEST" lazy="false">
<cache usage="read-write" region="ehcache.xml中的name的属性值"/>注意:这一句需要紧跟在class标签下面,其他位置无效。
hbm文件查找cache方法名的策略:如果不指定hbm文件中的region="ehcache.xml中的name的属性值",则使用name名为com.ouou.model.Videos的cache,
如果不存在与类名匹配的cache名称,则用defaultCache。
如果Videos包含set集合,则需要另行指定其cache
例如Videos包含Tags集合,则需要
添加如下配置到ehcache.xml中
<cache name="com.ouou.model.Tags"
maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120"
timeToLiveSeconds="120" overflowToDisk="false" />
另,针对查询缓存的配置如下:
<cache name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="true"/>
<cache name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="10000"
eternal="false"
timeToLiveSeconds="120"
overflowToDisk="true"/>
3、 选择缓存策略依据:
<cache usage="transactional|read-write|nonstrict-read-write|read-only" (1)/>
ehcache不支持transactional,其他三种可以支持。
read-only:无需修改, 那么就可以对其进行只读 缓存,注意,在此策略下,如果直接修改数据库,即使能够看到前台显示效果,
但是将对象修改至cache中会报error,cache不会发生作用。另:删除记录会报错,因为不能在read-only模式的对象从cache中删除。
read-write:需要更新数据,那么使用读/写缓存 比较合适,前提:数据库不可以为serializable transaction isolation level
(序列化事务隔离级别)
nonstrict-read-write:只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,
那么比较适合使用非严格读/写缓存策略。
4、 调试时候使用log4j的log4j.logger.org.hibernate.cache=debug,更方便看到ehcache的操作过程,主要用于调试过程,实际应用发布时候,请注释掉,以免影响性能。
5、 使用ehcache,打印sql语句是正常的,因为query cache设置为true将会创建两个缓存区域:一个用于保存查询结果集 (
org.hibernate.cache.StandardQueryCache);另一个则用于保存最近查询的一系列表的时间戳(org.hibernate.cache.UpdateTimestampsCache)。
请注意:在查询缓存中,它并不缓存结果集中所包含的实体的确切状态;它只缓存这些实体的标识符属性的值、以及各值类型的结果。
需要将打印sql语句与最近的cache内容相比较,将不同之处修改到cache中,所以查询缓存通常会和二级缓存一起使用。
Ehcache的配置说明
<ehcache>
<!--
磁盘存储配置:
用来指定缓存在磁盘上的存储位置。可以使用JavaVM环境变量(user.home, user.dir, java.io.tmpdir)
-->
<diskStore path = "/var/apps/cache/" />
<!--
指定CacheManagerEventListenerFactory,这个对象在缓存添加的时候会得到相应的通知
CacheManagerEventListenerFactory的属性
*class - CacheManagerEventListenerFactory的一个实现类
*properties - CacheManagerEventListenerFactory的属性值,以逗号(,)分割多个属性
如果没有实现类被指定,则系统不创建CacheManager的监听器,没有默认值
-->
<cacheManagerEventListenerFactory class="" properties="" />
<!--
在进行分布式缓存的应用时候需要指定CacheManagerPeerProviderFactory,
用来生成CacheManagerPeerProvider的实例,以便和集群中的其他CacheManager通信。
*class -CacheManagerPeerProviderFactory的一个实现类
*properties - CacheManagerPeerProviderFactory的属性值,以逗号(,)分割多个属性
Ehcache内建了2种基于RMI分布系统的通信策略:
*automatic - 使用多播组。在一个节点加入或者推出集群的时候自动感应
*manual - 硬编码方式
目前的awf中不考虑分布缓存
-->
<cacheManagerPeerListenerFactory class="" properties="" />
<!--
缓存配置。
以下属性是必须的:
name - cache的标识符,在一个CacheManager中必须唯一
maxElementsInMemory - 在内存中缓存的element的最大数目
maxElementsOnDisk - 在磁盘上缓存的element的最大数目
eternal - 设定缓存的elements是否有有效期。如果为true,timeouts属性被忽略
overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
以下属性是可选的:
timeToIdleSeconds - 缓存element在过期前的空闲时间。默认为0,表示可空闲无限时间.
(如果指定了这个时间,是否在被hit的前超过了这个时间就会被remove?在内存缓存数目超限之前不会被remove)
timeToLiveSeconds - 缓存element的有效生命期。这个类似于timeouts,默认为0,不过期
(是否通常情况下应该大于等于timeToIdleSeconds,小于会如何?idle时间也会减小和这个数值一样)
diskPersistent - 在VM重启的时候是否持久化磁盘缓存,默认是false。
(测试一下true的情况?重载vm的时候会从磁盘进行序列化到对象)
diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒.
(测试一下0的时候会如何)
memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候,
移除缓存中element的策略。默认是LRU,可选的有LFU和FIFO
可对缓存中的element配置诸如监听器和加载器。Ehcahe内建了一些
*cacheEventListenerFactory - 监听缓存中element的put, remove, update和expire事件
*bootstrapCacheLoaderFactory - 启动时加载缓存的element
每个用来做分布式缓存都必须设定element的事件监听器,用来在各个CacheManager节点复制消息。
Ehcache内建了基于RMI的实现 - RMICacheReplicatorFactory
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronouly=true,
replicatePuts=true,
replicateUpdates=true,
replicateUpdateViaCopy=true,
replicateRemovals=true" />
-->
<cache .... />
<!--
默认的Cache配置。用来实现CacheManager.add(String cacheName)创建的缓存
-->
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120"
overflowToDisk="true" maxElementsOnDisk="1000000"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>