`
seaizon
  • 浏览: 145273 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate缓存(转)

阅读更多
Hibernate缓存
缓存可以简单的看成一个Map,通过key在缓存里面找value。

一、缓存简介  Cache In Hibernate
HIBERNATE中的CACHE有两级.
一级是在Session范围内的CACHE. 即每个Session有自己的一个CACHE, 当前操作的对象都会被保留在CACHE中. 但是Session关闭后这个CACHE也就没有. 可见这级CACHE的生命期是很短的. (使用id进行关键字存储:缓存的key就是ID,value是POJO)(缓存的是实体对象)
另一级CACHE是在SessionFactory范围的, 可以被来自同一个SessionFactory的Session共享. 在HIBERNATE的文档中称其为SECOND LEVEL CACHE. 显然后者的优势较明显, 也比较复合当前的使用环境.   它可以使用不同的缓存实现,如EhCache、JBossCache、OsCache等 (二级缓存是缓存实体对象的)
还有一个类型的CACHE就是QueryCache. 它的作用就是缓存一个Query以及Query返回对象的Identifier以及对象的类型. 有了QueryCache后就可以高效的使用SECOND LEVEL CACHE.
hibernate查询缓 存(hibernate默认是关闭的)
查询缓存是针对普通 属性结果集的缓存
对实体对象的结果集只缓存id
查询缓存的生命周期,当前关联的表发生修改,那么查询缓存生命周期结束
查询缓存的配置和使用:
1. 启用查询缓存:在hibernate.cfg.xml中加入:
<property name=”hibernate.cache.use_query_cache”>true</property>
2. 在程序中必须手动启用查询缓存,如:query.setCacheable(true);
QueryCache用来缓存查询语句, 及查询结果集中对象的Identifier与Type. 当再次使用已缓存的Query时, 就可以通过对象的Identifier与Type在SECOND LEVEL CACHE中查找实际的对象.
对于查询缓存来说,缓存的key是根据hql生成的sql,再加上参数,分页等信息(可以通过日志输出看到,不过它的输出不是很可读,最好改一下它的代码)。

注:一级缓存也叫session级的缓存或事务缓存。Hibernate二级缓存也称为进程级的缓存或SessionFactory级的缓存。二级缓存是全局缓存,它可以被所有的session共享。二级缓存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二级缓存。


二、缓存的范围
缓存的范围分为3类:
1.事务范围
     事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结束.事务范围的缓存使用内存作为存储介质,一级缓存就属于事务范围.
2.应用范围
     应用程序的缓存可以 被应用范围内的所有事务共享访问.缓存的生命周期依赖于应用的 生命周期,只有当应用结束时,缓存的生命周期才会结束.应用范围的缓存可以使用内存或硬盘作为存储介质,二级缓存就属于应用范围.
3.集群范围
     在集群环境中,缓存被一个机器或多个机器的进程共享,缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致,缓存中的数据通常采用对象的松散数据形式.
三、缓存的方式
有四种,分别为:
  CacheConcurrencyStrategy.NONE
  CacheConcurrencyStrategy.READ_ONLY,只读模式,在此模式下,如果对数据进行更新操作,会有异常;
  CacheConcurrencyStrategy.READ_WRITE,读写模式在更新缓存的时候会把缓存里面的数据换成一个锁,其它事务如果去取相应的缓存数据,发现 被锁了,直接就去数据库查询;
  CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,不严格的读写模式则不会的缓存数据加锁;
  CacheConcurrencyStrategy.TRANSACTIONAL,事务模式指缓存支持事务,当事务回滚时,缓存也能回滚,只支持JTA环境。

缓存的注释写法如下,加在Entity的java类上:
  @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
四、缓存的管理
  Hibernate的缓存管理
一级缓存的管理:
  evit(Object obj)  将指定的持久化对象从一级缓存中清除,释放对象所占用的内存资源,指定对象从持久化状态变为脱管状态,从而成为游离对象.
  clear()  将一级缓存中的所有持久化对象清除,释放其占用的内存资源
  contains(Object obj) 判断指定的对象是否存在于一级 缓存中.
  flush() 刷新一级缓存区的内容,使之与数据库数据保持同步.

  二级缓存的管理:   
   evict(Class arg0, Serializable arg1)  将某个类的指定ID的持久化对象从二级缓存中清除,释放对象所占用的资源.
evictCollection(String arg0)  将指定类的所有持久化对象的指定集合从二级缓存中清除,释放其占用的内存资源.

如何避免一次性大量的实体数据入库导致内存溢出
*先flush,再clear

如果数据量特别大,考虑采用jdbc实现,如果jdbc也不能满足要求,可以考虑采用数据库本身的特定导入工具

五、什么样的数据不适合放在二级缓存中来?
  下面这几种情况就不适合加载到 二级缓存中:
  1.经常被修改的数据
  2.绝对不允许出现并发访问的数据
  3.与其他应用共享的数据
  下面这己种情况合适加载到二级 缓存中:
  1.数据更新频率低
  2.允许偶尔出现并发问题的非重要数据
  3.不会被并发访问的数据
  4.常量数据
  5.不会被第三方修改的数据

六、二级缓存的配置
Hibernate的二级缓存功能是靠配置二级缓存插件来实现的,Hibernate为了集成这些插件,Hibernate提供了org.hibernate.cache.CacheProvider借口,它充当缓存插件与Hibernate之间的适配器 .

常用的二级缓存插件
EHCache  org.hibernate.cache.EhCacheProvider
OSCache  org.hibernate.cache.OSCacheProvider
SwarmCahe  org.hibernate.cache.SwarmCacheProvider
JBossCache  org.hibernate.cache.TreeCacheProvider

设置hibernate.cache.provider_class。
我们这里用ehcache,如
hibernate.cache.provider_class=net.sf.hibernate.cache.EhCacheProvider
由于这是HIBERNATE默认的CACHE提供者, 所以无须做什么设置.
只要在src中添加ehcache的配置文件ehcache.xml:
<ehcache>
    <diskStore path="java.io.tmpdir"/> 
 
    <defaultCache   maxElementsInMemory="10000"   eternal="false"  timeToIdleSeconds="120"          timeToLiveSeconds="120"  overflowToDisk="true"   />  
 
    <cache name="goncha.hb.bean.Person"   maxElementsInMemory="10"       eternal="false"   
        timeToIdleSeconds="100"  timeToLiveSeconds="100"  overflowToDisk="false"   />    
      <cache name="goncha.hb.bean.Address"  maxElementsInMemory="10"     eternal="false"   
        timeToIdleSeconds="100"  timeToLiveSeconds="100"  overflowToDisk="false"    />    
</ehcache> 
七、哪些方法支持缓存
*get()
*load()
*iterate()  (查询实体对象)
save()
查询缓存只对query.list()起作用


一级缓存测试:
1.Load测试: 在同一个session中发出两次load查询(1)
2.Get测试: 在同一个session中发出两次get查询(1)
3.iterate测试: 在同一个session中发出两次iterator查询(1(id)+N,1(id))
4.Iterate查询属性测试: 同一个session中发出两次查询属性(2次,iterate查询普通属性,一级缓存不会缓存,所以会发出sql)
5.同一个session中先save,再发出load查询save过的数据--save是使用缓存的
6.同一个session中先调用load查询,然后执行sessio.clear()或session.evict(),再调用load查询(2次)
       sessio.clear()或session.evict()可以管理一级缓存,一级缓存无法取消,但可以管理. 上面的语句都会发出sql 因为一级缓存中的实体被清除了
7.向数据库中批量加入1000条数据
       //每一定条数据就强制session将数据持久化,同时清除缓存,避免大量数据造成内存溢 出

开启二级缓存测试:
1.开启两个session中发出两次load查询(get与load一样,1次),
2.开启两个session,分别调用load,再使用sessionFactory清楚二级缓存(2次)
3.一级缓存和二级缓存的交互
       session.setCacheMode(CacheMode.GET);    //设置成 只是从二级缓存里读,不向二级缓存里写数据 (2)
       session.setCacheMode(CacheMode.PUT);  //设置成只是向二级缓存里写数据,不读数据 (2次)

开启hibernate查询缓存测试:
1.  开启查询缓存,关闭二级缓存,开启一个session,分别调用query.list  (查询属性)(1次)
2.  开启查询缓存,关闭二级缓存,开启两个session,分别调用query.list  (查询属性)
(1次)第二次没有去查询数据库,因为查询缓存生 命周期与session生命周期无关
3.  开启查询缓存,关闭二级缓存,开启两个session,分别调用query.iterate (查询属性)
(2次)第二去查询数据库,因为查询缓存只对query.list()起作用,对query.iterate()不起作用,也就是说query.iterate()不使用查询缓存
4.  关闭查询缓存,关闭二级缓存,开启两个session,分别调用query.list (查询实体对象)      第二去查询数据库,因为list默认每次都会发出查询sql
5.  开启查询缓存,关闭二级缓存,开启两个session,分别调用query.list (查询实体对象)      第二去查询数据库时,会发出N条sql语句,因为开启了查询缓存,关闭了二级缓存,那么查询缓存会缓存实体对象的id,所以hibernate会根据实体对象的id去查询相应的实体,如果缓存中不存在相应的实体,那么将发出根据实体id查询的sql语句,否则不会发出sql,使用缓存中的数据
6.  开启查询缓存,开启二级缓存,开启两个session,分别调用query.list (查询实体对象)      第二不会发出sql,因为开启了二级缓存和查询缓存,查询缓存缓存了实体对象的id列表,hibernate会根据实体对象的id列表到二级缓存中取得相应的数据
八、二级缓存在项目中的集成和使用
1.将echcache.xml文件拷贝到src下, 二级缓存hibernate默认是关闭的,手动开启
2.开启二级缓存,修改hibernate.cfg.xml文件,
<property name=”hibernate.cache.user_second_level_cache”>true</property>
3.指定缓存产品提供商
<property name=”hibernate.cache.provider_calss”>org.hibernate.cache.EhCacheProvider</property>
4.指定那些实体类使用二级缓存(两种方法,推 荐使用第二种)
第一种:在*.hbm.xml中,在<id>之前加入
<cache usage=”read-only” />, 使用二级缓存
第二种:在hibernate.cfg.xml配置文件中,在<mapping resource=”com/Studnet.hbm.xml” />后面加上:
<class-cache class=” com.Studnet” usage=”read-only” />

总结:
不要想当然的以为缓存一定能提高性能,仅仅在你能够驾驭它并且条件合适的情况下才是这样的。hibernate的二级缓存限制还是比较多的,不方便用jdbc可能会大大的降低更新性能。在不了解原理的情况下乱用,可能会有1+N的问题。不当的使用还可能导致读出脏数据。
如果受不了hibernate的诸多限制,那么还是自己在应用程序的层面上做缓存吧。
在越高的层面上做缓存,效果就会越好。就好像尽管磁盘有缓存,数据库还是要实现自己的缓存,尽管数据库有缓存,咱们的应用程序还是要做缓 存。因为底层的缓存它并不知道高层要用这些数据干什么,只能做的比较通用,而高层可以有针对性的实现缓存,所以在更高的级别上做缓存,效果也要好些吧。

对于性能的看法是:合理的性能而不是最高的性能。什么是合理的?用户能感觉到(或敏感的)的范围 内,不成为物理上业务处理的瓶颈,比如常说的3秒之内响应等。

转自:http://aumy2008.blogbus.com/logs/41093212.html
分享到:
评论

相关推荐

    深入理解Hibernate缓存

    ### 深入理解Hibernate缓存 #### 一、Hibernate缓存概述 Hibernate作为一款流行的Java持久层框架,为开发者提供了高效且灵活的数据访问能力。其中,缓存机制是Hibernate性能优化的重要组成部分之一。理解Hibernate...

    Hibernate缓存.doc

    Hibernate缓存.docHibernate缓存.doc

    Hibernate缓存深入详解 from ITEye

    **Hibernate缓存深入详解** 在Java企业级应用开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。然而,随着应用规模的扩大,数据访问性能成为了一个不可忽视的问题。这时,...

    Hibernate缓存技术研究

    ### Hibernate缓存技术研究 #### 一、引言 Hibernate是一种强大的对象-关系映射(Object-Relational Mapping,简称ORM)工具,主要用于Java环境下的应用程序。它能够将应用程序中的对象模型映射到关系型数据库的表...

    Java Hibernate缓存深入详解

    Java Hibernate缓存深入详解

    hibernate缓存机制

    Hibernate缓存机制是提高应用程序性能的关键技术之一,它通过存储数据副本减少对物理数据库的访问。缓存可以分为两层:第一级缓存和第二级缓存。 **第一级缓存**是内置在Session中的,它是不可卸载的,也称为...

    hibernate缓存深入详解.

    关于hibernate缓存的一个ppt课件,60+幻灯片,有需要的可以看一下

    Hibernate缓存,性能优化

    本文将深入探讨Hibernate缓存的原理、类型及其对性能优化的影响。 ### Hibernate缓存原理 Hibernate缓存主要分为一级缓存和二级缓存。一级缓存,也称为会话缓存(Session Cache),是默认启用的,由Hibernate自动...

    Hibernate缓存深入详解

    【Hibernate缓存深入详解】 在Java的持久化框架Hibernate中,缓存机制是提升系统性能的关键因素。它位于Hibernate应用和数据库之间,减少了对数据库的直接访问,从而提高了应用程序的运行速度。缓存中存储的是...

    Hibernate缓存与spring事务详解

    **标题:“Hibernate缓存与Spring事务详解”** 在IT领域,尤其是Java开发中,Hibernate作为一款流行的ORM(对象关系映射)框架,极大地简化了数据库操作。而Spring框架则以其全面的功能,包括依赖注入、AOP(面向切...

    hibernate缓存和事务

    Hibernate 是一个流行的对象关系映射(ORM)框架,它允许Java...通过理解Hibernate缓存和事务管理,以及如何有效地执行查询,开发者可以创建高效、健壮的Java应用程序,降低与数据库交互的复杂性,同时提升系统性能。

    hibernate缓存

    ### Hibernate缓存机制及优化策略 #### 一、概述 Hibernate作为一款优秀的对象关系映射(ORM)框架,在Java开发领域被广泛应用于数据库操作。它提供了丰富的缓存机制来提高应用性能并降低数据库访问压力。本文将...

    Hibernate缓存策略

    Hibernate缓存原理及调优策略 Hibernate缓存原理调优策略

    Hibernate缓存详解

    **Hibernate缓存详解** 在Java开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。为了提高数据访问性能,Hibernate引入了缓存机制,它可以减少对数据库的直接访问,从而提升应用的...

    hibernate缓存ehcache用法

    这篇博客文章“hibernate缓存ehcache用法”可能详细介绍了如何在Hibernate中配置和使用Ehcache。 首先,我们需要理解什么是缓存。缓存是一种存储技术,用于临时保存经常访问的数据,以减少对主存储器(如数据库)的...

    Hibernate教程25_Hibernate缓存

    **标题解析:** "Hibernate教程25_Hibernate缓存" 这个标题表明了我们要讨论的是关于Hibernate框架的第25个教程,重点是它的缓存机制。Hibernate是一个流行的Java对象关系映射(ORM)框架,它允许开发者用面向对象的...

    hibernate缓存深入详解

    hibernate缓存深入详解

Global site tag (gtag.js) - Google Analytics