1.EhCache是什么
2.EhCache的使用注意点
3.EhCache使用的场合
4.在项目做的实现
配置Spring+hibernate使用ehcache作为second-levelcache
大量数据流动是web应用性能问题常见的原因,而缓存被广泛的用于优化数据库应用。cache被设计为通过保存从数据库里load的数据来减少应用和数据库之间的数据流动。数据库访问只有当检索的数据不在cache里可用时才必要。hibernate可以用两种不同的对象缓存:first-levelcache 和 second-level cache。first-levelcache和Session对象关联,而second-level cache是和Session Factory对象关联。
下载ehcache,hibernate3.2必须要ehcache1.2以上才能支持。可以修改log4j配置文件log4j.logger.net.sf.hibernate.cache=debug查看日志
1.在类路径上ehcache.xml:
<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 -->
<diskStorepath="java.io.tmpdir"/>
<!--Default Cache configuration. These will appliedto caches programmatically created through
the CacheManager.
The following attributes are required:
maxElementsInMemory - Sets the maximum number of objects that will be created inmemory
eternal - Sets whether elements are eternal. Ifeternal, timeouts are ignoredand the
element is never expired.
overflowToDisk - Sets whether elements can overflow to disk when the in-memorycache
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 elementexpires
Is only used if the element is not eternal.
Optional attribute. A value of 0 means that an Element can idle forinfinity.
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 elementexpires.
Is only used if the element is not eternal.
Optional attribute. A value of 0 means that and Element can livefor infinity.
The default value is 0.
diskPersistent - Whether the disk store persists between restarts of the VirtualMachine.
The default value is false.
diskExpiryThreadInterval Seconds- The number of seconds between runsof the disk expiry thread. The default value
is 120 seconds.
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskPersistent="false"
diskExpiryThreadInterval Seconds="120"/>
<!-- Seehttp://ehcache.sourceforge.net/documentation/#mozTocId258426 forhow to configure caching for your objects -->
</ehcache>
2.applicationContext-hibernate.xml里HibernateSessionFactory配置:
<!-- Hibernate SessionFactory-->
<bean id="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource"ref="dataSource"/>
<propertyname="configLocation"><value>classpath:hibernate.cfg.xml</value></property>
<!-- The property below is commented out b/c itdoesn't work when run via
Ant in Eclipse. It works finefor individual JUnit tests and in IDEA ??
<propertyname="mappingJarLocations">
<list><value>file:dist/appfuse-dao.jar</value></list>
</property>
-->
<propertyname="hibernateProperties">
<props>
<propkey="hibernate.dialect">@HIBERNATE-DIALECT@</prop>
<!--<propkey="hibernate.show_sql">true</prop>-->
<propkey="hibernate.max_fetch_depth">3</prop>
<propkey="hibernate.hibernate.use_outer_join">true</prop>
<propkey="hibernate.jdbc.batch_size">10</prop>
<propkey="hibernate.cache.use_query_cache">true</prop>
<propkey="hibernate.cache.use_second_level_cache">true</prop>
<propkey="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<!--
<propkey="hibernate.use_sql_comments">false</prop>
-->
<!-- Create/update the database tables automaticallywhen the JVM starts up
<propkey="hibernate.hbm2ddl.auto">update</prop>-->
<!-- Turn batching off for better error messagesunder PostgreSQL
<propkey="hibernate.jdbc.batch_size">0</prop>-->
</props>
</property>
<propertyname="entityInterceptor">
<reflocal="auditLogInterceptor"/>
</property>
</bean>
说明:如果不设置“查询缓存”,那么hibernate只会缓存使用load()方法获得的单个持久化对象,如果想缓存使用findall()、list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话,就需要设置hibernate.cache.use_query_cache true 才行
3.model类里采用Xdoclet生成*.hbm.xml里的cachexml标签,即<cacheusage="read-only"/>
4.对于"querycache",需要在程序里编码:
<propkey="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<propkey="hibernate.cache.use_query_cache">true</prop>
这两句加到hibernateProperties中
<bean id="hibernateTemplate"class="org.springframework.orm.hibernate3.HibernateTemplate">
<propertyname="sessionFactory">
</property>
<property name="cacheQueries">
</property>
</bean>
添加此bean到applicationcontext.xml中。在各个DAO的bean中,更改如下
<propertyname="sessionFactory">
<ref bean="sessionFactory" />
</property>
改为
<propertyname="hibernateTemplate">
<ref bean="hibernateTemplate"/>
</property>
2、ehcache.xml文件放在classes根目录即可
3、pojo与ehcache.xml的配置关系
以com.ce.ceblog.pojos.CeblogJournal为例子
在CeblogJournal.hbm.xml中配置:
<class name="CeblogJournal" table="CEBLOG_JOURNAL"lazy="false">
<cache usage="read-write"region="ehcache.xml中的name的属性值"/>
注意:这一句需要紧跟在class标签下面,其他位置无效。
Ehcache.xml文件主体如下
<defaultCache maxElementsInMemory="10000"eternal="false" timeToIdleSeconds="1" timeToLiveSeconds="1"overflowToDisk="true" />
<cache name="com.ce.ceblog.pojos.CeblogJournal"maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="300"timeToLiveSeconds="600" overflowToDisk="true"/>
hbm文件查找cache方法名的策略:如果不指定hbm文件中的region="ehcache.xml中的name的属性值",则使用name名为com.ce.ceblog.pojos.CeblogJournal的cache,如果不存在与类名匹配的cache名称,则用defaultCache。
如果CeblogJournal包含set集合,则需要另行指定其cache
例如CeblogJournal包含ceblogReplySet集合,则需要
添加如下配置到ehcache.xml中
<cachename="com.ce.ceblog.pojos.CeblogJournal.ceblogReplySet"
maxElementsInMemory="10000" eternal="false"timeToIdleSeconds="300"
timeToLiveSeconds="600" overflowToDisk="true" />
另,针对查询缓存的配置如下:
<cachename="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="true"/>
<cachename="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="10000"
eternal="false"
timeToLiveSeconds="120"
overflowToDisk="true"/>
4、选择缓存策略依据:
<cacheusage="transactional|read-write|nonstrict-read-write|read-only"/>
ehcache不支持transactional,其他三种可以支持。
read- only:无需修改, 那么就可以对其进行只读缓存,注意,在此策略下,如果直接修改数据库,即使能够看到前台显示效果,但是将对象修改至cache中会报error,cache不会发生作用。另:删除记录会报错,因为不能在read-only模式的对象从cache中删除。
read-write:需要更新数据,那么使用读/写缓存 比较合适,前提:数据库不可以为serializable transactionisolation level(序列化事务隔离级别)
nonstrict-read-write:只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存策略。
5、调试时候使用log4j的log4j.logger.org.hibernate.cache=debug,更方便看到ehcache的操作过程,主要用于调试过程,实际应用发布时候,请注释掉,以免影响性能。
6、 使用ehcache,打印sql语句是正常的,因为querycache设置为true将会创建两个缓存区域:一个用于保存查询结果集(org.hibernate.cache.StandardQueryCache);另一个则用于保存最近查询的一系列表的时间戳(org.hibernate.cache.UpdateTimestampsCache)。请注意:在查询缓存中,它并不缓存结果集中所包含的实体的确切状态;它只缓存这些实体的标识符属性的值、以及各值类型的结果。需要将打印sql语句与最近的cache内容相比较,将不同之处修改到cache中,所以查询缓存通常会和二级缓存一起使用。