Hibernate二级缓存

Hibernate是一个很好的ORM,对于性能优化也提供了很多方案。其中缓存方案中有一级缓存(默认开启),二级缓存(默认关闭)。在我参与项目中开启了二级缓存,这是一个老项目,可是感觉没有很好的效果,于是就学习了hibernate的二级缓存,尝试解决问题。对于二级缓存的选择应当是根据自己的需求选择是否开启,开启到何种程度。
项目相关信息:

hibernate版本:4.3.8.Final
数据库:mysql 5.7.18

主要的缓存

  • EHCache:快速、轻量级、易用的线程内缓存。支持只读、读写缓存。支持内存,磁盘缓存。但不支持集群。
  • OSCache:一个大型解决方案的一部分,提供对jsp页面和任何对象的缓存,强大而又灵活。也支持只读,读写缓存,支持内存、磁盘缓存。同时提供基于JavaGroups or JMS的基础集群支持。
  • SwarmCache:提供基于JavaGroups的简单集群支持。支持只读、非严格读写。适合读远远多于写的应用。
  • JBoss TreeCache:提供了强大的同步以及事务缓存。如果需要一个具有事务能力的高速缓存架构,这将是一个很好的选择。当然,也支持集群。

缓存策略

  • Read-only: 这种策略适合一直读但不更新的情况,性能是最好的。
  • Read/write: 这种策略适合需要修改数据的情况,不过需要更多的性能消耗。
  • Nonstrict read/write: 这种策略不保证两个事务不会同时修改相同数据。适合大多时候读,极少需要修改。
  • Transactional: 仅能在JTA环境中使用的完全事务

重要的配置

<property name="hibernateProperties">
    <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="hibernate.show_sql">true</prop>
        <prop key="hibernate.format_sql">true</prop>
        <prop key="hibernate.hbm2ddl.auto">update</prop>
        <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="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>
    </props>
</property>

 

hibernate.cache.use_second_level_cache:开启二级缓存

hibernate.cache.use_query_cache:开启查询缓存

hibernate.cache.region.factory_class:缓存区实现类

hibernate.cache.provider_configuration_file_resource_path:缓存配置文件

defaultCache
        maxElementsInMemory="1000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        maxElementsOnDisk="1000000"
        overflowToDisk="true"
        memoryStoreEvictionPolicy="LRU">

</defaultCache>

maxElementsInMemory:内存中最大保存实体数

Eternal:是否永久保存

timeToIdleSeconds:缓存对象在多少秒内没有被使用就清除

timeToLiveSeconds:缓存对象在过期前可以缓存多少秒

maxElementsOnDisk:磁盘中最大保存实体数

overflowToDisk:系统宕机时是否保存到磁盘上

memoryStoreEvictionPolicy:清除对象的方式

二级缓存的开启

①开启二级缓存。

二级缓存默认是关闭的,开启需要在配置文件中手动添加:

<prop key="hibernate.cache.use_second_level_cache">true</prop>

除此,还需要对需要缓存的实体添加cache注解,注解如下:

@Entity
@Table(name = "user", schema = "", catalog = "")
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class UserEntity {
......
}

至此,当使用listgetload等时,获取的数据会添加到二级缓存中。

但是,只有使用loadget时才会使用二级缓存中的数据。因为这个时候二级缓存中仅仅使用entity的标识属性作为key来缓存实体。

List、条件查询都会直接从数据库中获取数据。(未开启条件查询时)

②开启查询缓存

查询缓存默认关闭,打开方式如下:

<prop key="hibernate.cache.use_query_cache">true</prop>

对于需要缓存查询语句需要添加”setCacheable(true)”

<prop key="hibernate.cache.use_query_cache">true</prop>

将会以本条sql语句作为key,如果查询语句中有参数,将会由参数组装成sql语句作为key

select
    this_.id as id1_2_0_,
    this_.name as name2_2_0_,
    this_.version as version3_2_0_
from
    test.user this_
where
    this_.id='0b0ee7bb-8fba-4f87-91c4-db69f249fcc4'

当下一次查询语句组装的sql语句于缓存的key一致时(相同的语句,相同的参数),才会使用二级缓存中的数据。

缓存中数据的添加更新删除

1,添加

对于对象的添加,listgetloadhqlsql获得的数据,都会以对象的标识属性为key进行缓存。

如果开启查询缓存,listhqlsql会进行两项缓存:①以对象的标识属性为key进行缓存;②以查询语句与参数组成的sql语句为key进行查询结果缓存。

2,删除与更新

①Read-only 

不能更新删除从缓存中获取的对象。

通过hql、sql等直接修改删除的,会清除该实体类的所有entity,以及相关查询缓存。

②其他

Updatedelete数据时,如果数据是从缓存中读取的或依据对象标识属性从数据库读取的(即要修改的属性是以标识属性从缓存或数据库中获取),再做修改,仅清除该实体,以及相关的查询缓存。

如果通过hqlsqlupdatedelete,则清除实体类的所有entity,以及相关的查询缓存。

 参考:

http://www.devx.com/dbzone/Article/29685?pf=true

http://www.iteye.com/topic/18904 

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011142426/article/details/78533123
个人分类: Hibernate
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭