`
javaeyetodj
  • 浏览: 431441 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

hibernate 二级缓存(二)

阅读更多

转自 http://terryjs.iteye.com/blog/751471

1 启用 Hibernate 二级缓存

 

Hibernate 二级缓存分为两部分, class 缓存和查询缓存,其获取对象的方式有所不同,但两者也有联系,查询缓存必须以 class 缓存为基础才能起作用,否则只会使效率更低。

我们这里使用的二级缓存是通过 ehcache 第三方插件实现的。

 

1.1 配置 Hibernate.cfg.xml

启用 class 缓存:

             

Xml代码 复制代码
  1. <property name="hibernate.cache.provider_class">  
  2.   
  3.                      org.hibernate.cache.EhCacheProvider   
  4.   
  5.               </property>  
<property name="hibernate.cache.provider_class">

                     org.hibernate.cache.EhCacheProvider

              </property>
 

 

       启用查询缓存:

             

Xml代码 复制代码
  1. <property name="hibernate.cache.use_query_cache">true</property>  
<property name="hibernate.cache.use_query_cache">true</property>

 

1.2 配置 Spring 框架中的 hibernate

      启用 class 缓存:

Xml代码 复制代码
  1. <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>  
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
 

启用查询缓存:

Xml代码 复制代码
  1. <prop key="hibernate.cache.use_query_cache">true</prop>  
<prop key="hibernate.cache.use_query_cache">true</prop>

 

 

1.3 配置 ehcache

       Ehcache 配置文件为 ehcache.xml ,默认配置为:

             

Xml代码 复制代码
  1. <ehcache>  
  2.   
  3.                   <diskStore path="java.io.tmpdir"/>  
  4.   
  5.                   <defaultCache  
  6.   
  7.                    maxElementsInMemory="10000"  
  8.   
  9.                    eternal="false"  
  10.   
  11.                    timeToIdleSeconds="1800"  
  12.   
  13.                    timeToLiveSeconds="1800"  
  14.   
  15.                    overflowToDisk="true"  
  16.   
  17.             />  
  18.   
  19. <SPAN lang=EN-US><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: small"></ehcache></SPAN>  
  20. </SPAN>  
<ehcache>

                  <diskStore path="java.io.tmpdir"/>

                  <defaultCache

                   maxElementsInMemory="10000"

                   eternal="false"

                   timeToIdleSeconds="1800"

                   timeToLiveSeconds="1800"

                   overflowToDisk="true"

            />

</ehcache>


 

 


       其中各项内容的含义为:

1          diskStore :代表当二级缓存对象数据在内存中溢出,如果需要写入文件系统时的文件目录。

2          defaultCache :默认的 calss 缓存配置,如果某个对象没有其专有的配置时, ehcache 一律启用默认配置。

3          maxElementInMemory :对象在内存中可存放的最大数量。

4          eternal :表示对象永不过期,如果选 true 5 6 两项无效。

5          timeToIdleSeconds :对象的空闲状态过期时间,单位为秒, 0 为可以无限制空闲。

6          timeToLiveSeconds :对象存在的最长时间,单位为秒(注意,如果该项比 5 项要小,则第 5 项无意义), 0 为永不过期。

7          overflowToDisk :当对象在内存中的数量超过 maxElementInMemory 值时,如果该项为 true ,则 ehcahe 会把对象数据写入 diskStore 项指定的目录。

如果需要对某个具体对象进行单独配置时,可以加上一组 cache 配置,例如:

           

Xml代码 复制代码
  1. <cache name="com.juyee.mp.bean.SysCodelist"  
  2.   
  3.             maxElementsInMemory="10000"  
  4.   
  5.             eternal="true"  
  6.   
  7.             timeToIdleSeconds="1800"  
  8.   
  9.             timeToLiveSeconds="0"  
  10.   
  11.             overflowToDisk="true"  
  12.   
  13.          />  
<cache name="com.juyee.mp.bean.SysCodelist"

            maxElementsInMemory="10000"

            eternal="true"

            timeToIdleSeconds="1800"

            timeToLiveSeconds="0"

            overflowToDisk="true"

         />
 

 

另外还有两个特殊的 cache 配置:

  

Xml代码 复制代码
  1. <cache name="org.hibernate.cache.UpdateTimestampsCache"  
  2.   
  3.           maxElementsInMemory="5000"  
  4.   
  5.           eternal="true"  
  6.   
  7.           timeToIdleSeconds="1800"  
  8.   
  9.           timeToLiveSeconds="0"                
  10.   
  11.           overflowToDisk="true"/>  
  12.   
  13.    <cache name="org.hibernate.cache.StandardQueryCache"  
  14.   
  15.           maxElementsInMemory="10000"  
  16.   
  17.           eternal="false"  
  18.   
  19.           timeToIdleSeconds="1800"  
  20.   
  21.           timeToLiveSeconds="0"  
  22.   
  23.           overflowToDisk="true"/>  
  <cache name="org.hibernate.cache.UpdateTimestampsCache"

            maxElementsInMemory="5000"

            eternal="true"

            timeToIdleSeconds="1800"

            timeToLiveSeconds="0"             

            overflowToDisk="true"/>

     <cache name="org.hibernate.cache.StandardQueryCache"

            maxElementsInMemory="10000"

            eternal="false"

            timeToIdleSeconds="1800"

            timeToLiveSeconds="0"

            overflowToDisk="true"/>
 

 

这两个 cache 配置对应查询缓存,具体作用如下(摘用别人的描述):

       “当 hibernate 更新数据库的时候,它怎么知道更新哪些查询缓存呢? hibernate 在一个地方维护每个表的最后更新时间,其实也就是放在上面 UpdateTimestampsCache 所指定的缓存配置里面。

当通过 hibernate 更新的时候, hibernate 会知道这次更新影响了哪些表。然后它更新这些表的最后更新时间。每个缓存都有一个生成时间和这个缓存所查询的表,当 hibernate 查询一个缓存是否存在的时候,如果缓存存在,它还要取出缓存的生成时间和这个缓存所查询的表,然后去查找这些表的最后更新时间,如果有一个表在生成时间后更新过了,那么这个缓存是无效的。

可以看出,只要更新过一个表,那么凡是涉及到这个表的查询缓存就失效了,因此查询缓存的命中率可能会比较低。”

       当然,如果没有这两个配置,则 ehcache 将为查询缓存启用默认配置。

 

 

2 如何使用 class 缓存

 

2.1 对象缓存   

Class 缓存的作用主要是在内存中保存某个具体对象,当用户第一次通过 get iterator 方式取出对象时,系统会先从 class 缓存中去找,如果没有再通过 sql 语句去数据库中查找相关记录,并将查询到的对象放入内存中。

       实例:对某个对象使用二级缓存,只需要在该对象的 hbm 文件中配置即可

<cache usage="read-write"/>

       我们注意到其中 usage 这个选项,它有多个选择,对应不同的含义,经常有这两种种:

1          read-only :只对缓存中的对象进行读操作。

2          read-write :当对象被 update 时,缓存中和数据库中一同被修改(缓存不支持事务回滚)。

 

 

2.2 关联缓存

目前我们仅仅实现了对一个对象的缓存,那如何对该对象的关联对象集合进行缓存呢?

实例:对某个对象的关联对象集合的二级缓存,需要在该对象的 hbm 文件中 set 配置进行修改

       

Xml代码 复制代码
  1. <set name="children" lazy="true" order-by="treeid asc">  
  2.   
  3.       <cache usage="read-write"/>  
  4.   
  5.                <key column="PARENTID"/>  
  6.   
  7.                <one-to-many class="SysCodelist"/>  
  8.   
  9.         </set>   
      <set name="children" lazy="true" order-by="treeid asc">

            <cache usage="read-write"/>

                     <key column="PARENTID"/>

                     <one-to-many class="SysCodelist"/>

              </set> 
 

          

注意:

1          只对 one-to-many 有效,而且仅仅缓存的是关联对象的 id 集合,如果需要实现完全缓存,则需要对关联的对象也配置成使用二级缓存。

2          集合缓存是独立的,不受关联对象添加、删除的影响,如果要修改集合内容,必须对这个集合本身进行修改,例如: codelist.getChildren().add()

 

 

3 如何使用查询缓存

 

       查询缓存,目的是为了将通过 list() 方法的查询结果存入缓存中,并实现对语句的缓存,如果下次用户在使用这条语句进行查询时,将直接从缓存中获取对象数据。

       这里要注意的是,查询缓存必须配合 class 缓存使用,如果只启用查询缓存,不对查询对象启用二级缓存,则会大大降低查询效率。

因为,当第一次通过启用查询缓存的 session 进行语句查询时,系统只执行一次数据库查询将所有的记录取出,并将对象存入 class 缓存,语句及 id 集合存入查询缓存;而当用户第二次查询该语句时,系统将先执行去查询缓存中查找,取出所有符合条件的 id 集合,如果这时候该对象的 class 缓存没启用或在 class 缓存中已过期,系统将根据 id ,一个个去数据库 load ,实际上是进行了 1+N 次查询。

实际上,在我们系统中,并不是对所有对象都要进行二级缓存,而 spring 框架中提供的 hibernate 方法,虽然有 getHibernateTemplate().setCacheQueries() ,但该方法影响的是全局的配置,一旦启用,将会对不需要缓存的查询造成不良影响。

于是,我自己在 hibernateService() 中添加了一个方法:

  

Java代码 复制代码
  1. public List findByCachedQuery(final String hql)   
  2.   
  3.    {   
  4.   
  5.        return (List) getHibernateTemplate().execute(new HibernateCallback() {   
  6.   
  7.            public Object doInHibernate(Session session) throws HibernateException {   
  8.   
  9.                Query queryObject = session.createQuery(hql);   
  10.   
  11.                queryObject.setCacheable(true);   
  12.   
  13.                if (getHibernateTemplate().getQueryCacheRegion() != null) {   
  14.   
  15.                    queryObject.setCacheRegion(getHibernateTemplate().getQueryCacheRegion());   
  16.   
  17.                }   
  18.   
  19.                return queryObject.list();   
  20.   
  21.            }   
  22.   
  23.        }, true);   
  24.   
  25.    }  
 public List findByCachedQuery(final String hql)

    {

        return (List) getHibernateTemplate().execute(new HibernateCallback() {

            public Object doInHibernate(Session session) throws HibernateException {

                Query queryObject = session.createQuery(hql);

                queryObject.setCacheable(true);

                if (getHibernateTemplate().getQueryCacheRegion() != null) {

                    queryObject.setCacheRegion(getHibernateTemplate().getQueryCacheRegion());

                }

                return queryObject.list();

            }

        }, true);

    }
 

 

这样,将只在 session 范围内启用查询缓存,一旦该 session 结束了,那么查询缓存也将回复默认配置。

注意:使用时只支持 hql

 

4 注意事项

       在使用二级缓存时,注意,所有对数据库的修改都必须走hibernate,如果从其他系统来或使用sql语句来修改数据库相关记录,那么将对二级缓存的数据不会造成影响,换句话说,缓存中的对象数据将和数据库中的不一致。

 

分享到:
评论

相关推荐

    hibernate二级缓存实例

    在这个"hibernate二级缓存实例"中,我们将深入探讨二级缓存的原理、配置以及在实际项目中的应用。 首先,我们需要了解一级缓存和二级缓存的区别。一级缓存是Session级别的,每个Session都有自己的一级缓存,用于...

    Hibernate二级缓存

    Hibernate二级缓存是一种提高应用程序性能的技术,它将数据存储在SessionFactory级别的缓存中,使得数据可以在不同的Session之间共享。这与一级缓存(Session级别)不同,一级缓存仅存在于单个Session生命周期内,当...

    hibernate一级缓存和二级缓存的区别与联系

    总结来说,Hibernate 的一级缓存和二级缓存都是为了提高数据访问效率,但它们在范围和并发控制方面有所不同。一级缓存是事务级别的,保证了数据的强一致性,而二级缓存提供了更多的灵活性,可以跨事务共享,但需要...

    hibernate二级缓存示例源码

    **hibernate二级缓存详解** Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,极大地简化了数据库操作。然而,在处理大量数据时,性能优化显得尤为重要,这就是二级缓存的作用。本文将深入探讨Hibernate...

    hibernate 二级缓存详解

    Hibernate 二级缓存是针对SessionFactory级别的全局缓存,与一级缓存(Session级别)不同,一级缓存只在单个Session生命周期内有效。二级缓存则允许不同Session之间共享数据,提高了数据访问效率,减少了对数据库的...

    hibernate一级缓存、二级缓存和查询缓存

    **hibernate一级缓存、二级缓存和查询缓存** 在Java的持久化框架Hibernate中,缓存机制是提高应用程序性能的关键要素。缓存能够减少数据库的访问次数,提高数据读取速度,并且在一定程度上降低了系统的负载。本文将...

    hibernate二级缓存包

    Hibernate二级缓存是Java开发中使用Hibernate框架进行数据持久化时优化性能的一种重要技术。它在一级缓存(Session级别的缓存)的基础上,提供了一个全局的、跨会话的数据存储层,可以显著减少对数据库的访问,从而...

    day37 05-HIbernate二级缓存:一级缓存更新同步到二级缓存及二级缓存配置文件

    本篇文章将深入探讨Hibernate的二级缓存机制,以及如何进行一级缓存与二级缓存的同步,同时还会介绍二级缓存的配置文件设置。 一级缓存是Hibernate默认提供的缓存,每个SessionFactory实例都有一个一级缓存。当对象...

    Hibernate 二级缓存

    Hibernate 二级缓存

    hibernate二级缓存

    Hibernate 二级缓存是一种高效的数据存储机制,它能够显著提升Web应用的性能,尤其是在处理大量数据流动时。缓存的主要目标是减少应用与数据库之间的交互次数,从而降低延迟并减轻数据库服务器的压力。在Hibernate...

    Hibernate一级缓存和二级缓存

    **二、Hibernate二级缓存** 二级缓存是SessionFactory级别的,跨越了多个Session,可以被多个线程共享。它通常由第三方插件如EhCache、Infinispan等提供。二级缓存分为以下几种类型: 1. **集合缓存**:用于存储...

    hibernate二级缓存java包下载

    二级缓存是 Hibernate 缓存策略的一部分,它在应用程序的多个会话之间共享数据,进一步优化了数据库访问效率。 二级缓存分为以下关键知识点: 1. **一级缓存与二级缓存的区别**: - 一级缓存:每个 Hibernate ...

    Hibernate 二级缓存 总结整理

    **Hibernate 二级缓存总结整理** 在Java的持久化框架中,Hibernate是一个广泛使用的ORM(对象关系映射)工具,它极大地简化了数据库操作。在处理大数据量或高并发的场景下,为了提高性能和减少数据库负载,...

    springboot+jpa(hibernate配置redis为二级缓存) springboot2.1.4

    通过以上步骤,我们就成功地在Spring Boot 2.1.4.RELEASE项目中配置了使用Redis作为Hibernate二级缓存的环境。这将显著提升数据库查询效率,减少对数据库的压力,尤其在高并发场景下,效果尤为明显。记得在实际生产...

    Spring集成的Hibernate配置二级缓存

    以EhCache为例,我们需要在项目中引入ehcache-core或ehcache的依赖,并在Hibernate配置文件(hibernate.cfg.xml或persistence.xml)中启用二级缓存,添加如下配置: ```xml &lt;property name="hibernate.cache.use_...

    hibernate二级缓存所需要的 jar包

    本篇将详细介绍Hibernate二级缓存的概念、作用以及所需jar包的作用。 一、Hibernate二级缓存概念 Hibernate的一级缓存是指Session级别的缓存,每个Session内部都有一个一级缓存,用于存储实体对象,当Session关闭时...

    为Spring集成的Hibernate配置二级缓存

    2. **配置Hibernate**:在Hibernate的配置文件`hibernate.cfg.xml`中启用二级缓存并指定缓存提供商。以下是一个使用Ehcache的示例: ```xml &lt;property name="hibernate.cache.use_second_level_cache"&gt;true ...

    hibernate 二级缓存

    本篇文章将深入探讨Hibernate二级缓存的概念、工作原理以及如何在实际项目中设置和使用。 **一、二级缓存概念** 一级缓存是每个Hibernate Session内部的一个内存区域,用于存储Session期间的操作对象。当Session...

    Hibernate 一级缓存和二级缓存的区别

    Hibernate 一级缓存和二级缓存的区别

    hibernate二级缓存(包括注解方式)

    标题“hibernate二级缓存(包括注解方式)”指出了本文将探讨的是Hibernate框架中的二级缓存机制,并且会涉及使用注解的方式进行配置。Hibernate是一个流行的对象关系映射(ORM)框架,它允许开发者在Java应用中使用...

Global site tag (gtag.js) - Google Analytics