hibernate二级缓存hibernate 3除了一级缓存,二级缓存,还有其它的缓存吗?

hibernate二级缓存  时间:2021-08-24  阅读:()

hibernate二级缓存什么时候用

Hibernate缓存何时使用和如何使用? Hibernate缓存分为二级,第一级存放于session中称为一级缓存,默认带有且不能卸载。

第二级是由sessionFactory控制的进程级缓存。

是全局共享的缓存,凡是会调用二级缓存的查询方法 都会从中受益。

1. 关于hibernate缓存的问题: 1.1. 基本的缓存原理 Hibernate缓存分为二级, 第一级存放于session中称为一级缓存,默认带有且不能卸载。

第二级是由sessionFactory控制的进程级缓存。

是全局共享的缓存,凡是会调用二级缓存的查询方法 都会从中受益。

只有经正确的配置后二级缓存才会发挥作用。

同时在进行条件查询时必须使用相应的方法才能从缓存中获取数据。

比如 Query.iterate()方法、load、get方法等。

必须注意的是session.find方法永远是从数据库中获取数据,不会从二级缓存中获 取数据,即便其中有其所需要的数据也是如此。

查询时使用缓存的实现过程为:首先查询一级缓存中是否具有需要的数据,如果没有,查询二级缓存,如果二级缓存中也没有,此时再执行查询数据库的工作。

要注意的是:此3种方式的查询速度是依次降低的。

1.2. 存在的问题 1.2.1. 一级缓存的问题以及使用二级缓存的原因 因为Session的生命期往往很短,存在于Session内部的第一级最快缓存的生命期当然也很短,所以第一级缓存的命中率是很低的。

其对系统性 能的改善也是很有限的。

当然,这个Session内部缓存的主要作用是保持Session内部数据状态同步。

并非是hibernate为了大幅提高系统性 能所提供的。

为了提高使用hibernate的性能,除了常规的一些需要注意的方法比如: 使用延迟加载、迫切外连接、查询过滤等以外,还需要配置hibernate的二级缓存。

其对系统整体性能的改善往往具有立竿见影的效果! (经过自己以前作项目的经验,一般会有3~4倍的性能提高) 1.2.2. N+1次查询的问题 1.2.2.1 什么时候会遇到1+N的问题? 前提:Hibernate默认表与表的关联方法是fetch="select",不是fetch="join",这都是为了懒加载而准备的。

1)一对多(<set><list>) ,在1的这方,通过1条sql查找得到了1个对象,由于关联的存在 ,那么又需要将这个对象关联的集合取出,所以合集数量是n还要发出n条sql,于是本来的1条sql查询变成了1 +n条 。

2)多对一<many-to-one> ,在多的这方,通过1条sql查询得到了n个对象,由于关联的存在,也会将这n个对象对应的1 方的对象取出, 于是本来的1条sql查询变成了1 +n条 。

3)iterator 查询时,一定先去缓存中找(1条sql查集合,只查出ID),在没命中时,会再按ID到库中逐一查找, 产生1+n条SQL 1.2.2.2 怎么解决1+N 问题? 1 )lazy=true, hibernate3开始已经默认是lazy=true了;lazy=true时不会立刻查询关联对象,只有当需要关联对象(访问其属性,非id字段)时才会发生查询动作。

2)使用二级缓存, 二级缓存的应用将不怕1+N 问题,因为即使第一次查询很慢(未命中),以后查询直接缓存命中也是很快的。

刚好又利用了1+N 。

3) 当然你也可以设定fetch="join",一次关联表全查出来,但失去了懒加载的特性。

执行条件查询时,iterate()方法具有著名的 “n+1”次查询的问题,也就是说在第一次查询时iterate方法会执行满足条件的查询结果数再加一次(n+1)的查询。

但是此问题只存在于第一次查询 时,在后面执行相同查询时性能会得到极大的改善。

此方法适合于查询数据量较大的业务数据。

但是注意:当数据量特别大时(比如流水线数据等)需要针对此持久化对象配置其具体的缓存策略,比如设置其存在于缓存中的最大记录数、缓存存在的时间等参数,以避免系统将大量的数据同时装载入内存中引起内存资源的迅速耗尽,反而降低系统的性能!!! 1.3. 使用hibernate二级缓存的其他注意事项: 1.3.1. 关于数据的有效性 另外,hibernate会自行维护二级缓存中的数据,以保证缓存中的数据和数据库中的真实数据的一致性!无论何时,当你调用save()、 update()或 saveOrUpdate()方法传递一个对象时,或使用load()、 get()、list()、iterate() 或scroll()方法获得一个对象时, 该对象都将被加入到Session的内部缓存中。

当随后flush()方法被调用时,对象的状态会和数据库取得同步。

也就是说删除、更新、增加数据的时候,同时更新缓存。

当然这也包括二级缓存! 只要是调用hibernate API执行数据库相关的工作。

hibernate都会为你自动保证 缓存数据的有效性!! 但是,如果你使用了JDBC绕过hibernate直接执行对数据库的操作。

此时,Hibernate不会/也不可能自行感知到数据库被进行的变化改动,也就不能再保证缓存中数据的有效性!! 这也是所有的ORM产品共同具有的问题。

幸运的是,Hibernate为我们暴露了Cache的清除方法,这给我们提供了一个手动保证数据有效性的机会!! 一级缓存,二级缓存都有相应的清除方法。

其中二级缓存提供的清除方法为: 按对象class清空缓存 按对象class和对象的主键id清空缓存 清空对象的集合中的缓存数据等。

1.3.2. 适合使用的情况 并非所有的情况都适合于使用二级缓存,需要根据具体情况来决定。

同时可以针对某一个持久化对象配置其具体的缓存策略。

适合于使用二级缓存的情况: 1、数据不会被第三方修改; 一般情况下,会被hibernate以外修改的数据最好不要配置二级缓存,以免引起不一致的数据。

但是如果此数据因为性能的原因需要被缓存,同时又 有可能被第3方比如SQL修改,也可以为其配置二级缓存。

只是此时需要在sql执行修改后手动调用cache的清除方法。

以保证数据的一致性 2、数据大小在可接收范围之内; 如果数据表数据量特别巨大,此时不适合于二级缓存。

原因是缓存的数据量过大可能会引起内存资源紧张,反而降低性能。

如果数据表数据量特别巨大,但是经常使用的往往只是较新的那部分数据。

此时,也可为其配置二级缓存。

但是必须单独配置其持久化类的缓存策略,比如最大缓存数、缓存过期时间等,将这些参数降低至一个合理的范围(太高会引起内存资源紧张,太低了缓存的意义不大)。

3、数据更新频率低; 对于数据更新频率过高的数据,频繁同步缓存中数据的代价可能和 查询缓存中的数据从中获得的好处相当,坏处益处相抵消。

此时缓存的意义也不大。

4、非关键数据(不是财务数据等) 财务数据等是非常重要的数据,绝对不允许出现或使用无效的数据,所以此时为了安全起见最好不要使用二级缓存。

因为此时 “正确性”的重要性远远大于 “高性能”的重要性。

2. 目前系统中使用hibernate缓存的建议 2.1. 目前情况 一般系统中有三种情况会绕开hibernate执行数据库操作: 1、多个应用系统同时访问一个数据库 此种情况使用hibernate二级缓存会不可避免的造成数据不一致的问题,此时要进行详细的设计。

比如在设计上避免对同一数据表的同时的写入操作, 使用数据库各种级别的锁定机制等。

2、动态表相关 所谓“动态表”是指在系统运行时根据用户的操作系统自动建立的数据表。

比如“自定义表单”等属于用户自定义扩展开发性质的功能模块,因为此时数据表是运行时建立的,所以不能进行hibernate的映射。

因此对它的操作只能是绕开hibernate的直接数据库JDBC操作。

如果此时动态表中的数据没有设计缓存,就不存在数据不一致的问题。

如果此时自行设计了缓存机制,则调用自己的缓存同步方法即可。

3、使用sql对hibernate持久化对象表进行批量删除时 此时执行批量删除后,缓存中会存在已被删除的数据。

分析: 当执行了第3条(sql批量删除)后,后续的查询只可能是以下三种方式: a. session.find()方法: 根据前面的总结,find方法不会查询二级缓存的数据,而是直接查询数据库。

所以不存在数据有效性的问题。

b. 调用iterate方法执行条件查询时: 根据iterate查询方法的执行方式,其每次都会到数据库中查询满足条件的id值,然后再根据此id 到缓存中获取数据,当缓存中没有此id的数据才会执行数据库查询; 如果此记录已被sql直接删除,则iterate在执行id查询时不会将此id查询出来。

所以,即便缓存中有此条记录也不会被客户获得,也就不存在不一致的情况。

(此情况经过测试验证) c. 用get或load方法按id执行查询: 客观上此时会查询得到已过期的数据。

但是又因为系统中执行sql批量删除一般是针对中间关联数据表,对于中间关联表的查询一般都是采用条件查询 ,按id来查询某一条关联关系的几率很低,所以此问题也不存在! 如果某个值对象确实需要按id查询一条关联关系,同时又因为数据量大使用 了sql执行批量删除。

当满足此两个条件时,为了保证按id 的查询得到正确的结果,可以使用手动清楚二级缓存中此对象的数据的方法!!(此种情况出现的可能性较小) 2.2. 建 议 1、建议不要使用sql直接执行数据持久化对象的数据的更新,但是可以执行 批量删除。

(系统中需要批量更新的地方也较少) 2、如果必须使用sql执行数据的更新,必须清空此对象的缓存数据。

调用 SessionFactory.evict(class) SessionFactory.evict(class,id)等方法。

3、在批量删除数据量不大的时候可以直接采用hibernate的批量删除,这样就不存在绕开hibernate执行sql产生的缓存数据一致性的问题。

4、不推荐采用hibernate的批量删除方法来删除大批量的记录数据。

原因是hibernate的批量删除会执行1条查询语句外加 满足条件的n条删除语句。

而不是一次执行一条条件删除语句!! 当待删除的数据很多时会有很大的性能瓶颈!!!如果批量删除数据量较大,比如超过50条,可以采用JDBC直接删除。

这样作的好处是只执行一条sql删除语句,性能会有很大的改善。

同时,缓存数据同步的问题,可以采用 hibernate清除二级缓存中的相关数据的方法。

调 用 SessionFactory.evict(class) ; SessionFactory.evict(class,id)等方法。

所以说,对于一般的应用系统开发而言(不涉及到集群,分布式数据同步问题等),因为只在中间关联表执行批量删除时调用了sql执行,同时中间关联表 一般是执行条件查询不太可能执行按id查询。

所以,此时可以直接执行sql删除,甚至不需要调用缓存的清除方法。

这样做不会导致以后配置了二级缓存引起数 据有效性的问题。

退一步说,即使以后真的调用了按id查询中间表对象的方法,也可以通过调用清除缓存的方法来解决。

3、具体的配置方法 根据我了解的很多hibernate的使用者在调用其相应方法时都迷信的相信“hibernate会自行为我们处理性能的问题”,或者 “hibernate 会自动为我们的所有操作调用缓存”,实际的情况是hibernate虽然为我们提供了很好的缓存机制和扩展缓存框架的支持,但是必须经过正确的调用其才有 可能发挥作用!!所以造成很多使用hibernate的系统的性能问题,实际上并不是hibernate不行或者不好,而是因为使用者没有正确的了解其使 用方法造成的。

相反,如果配置得当hibernate的性能表现会让你有相当“惊喜的”发现。

下面我讲解具体的配置方法。

ibernate提供了二级缓存的接口: net.sf.hibernate.cache.Provider, 同时提供了一个默认的 实.sf.hibernate.cache.HashtableCacheProvider, 也可以配置 其他的实现 比如ehcache,jbosscache等。

具体的配置位置位于hibernate.cfg.xml文件中
  • <property?name="hibernate.cache.use_query_cache">true</property>?
  • <property?name="hibernate.cache.provider_class"&.sf.hibernate.cache.HashtableCacheProvider</property>? 很多的hibernate使用者在 配置到 这一步 就以为 完事了, 注意:其实光这样配,根本就没有使用hibernate的二级缓存。

    同时因为他们在使用hibernate时大多时候是马上关闭session,所 以,一级缓存也没有起到任何作用。

    结果就是没有使用任何缓存,所有的hibernate操作都是直接操作的数据库!!性能可以想见。

    正确的办法是除了以上的配置外还应该配置每一个vo对象的具体缓存策略,在影射文件中配置。

    例如:
  • <hibernate-mapping>?
  • <class?name=&.sobey.sbm.model.entitySystem.vo.DataTypeVO"?table="dcm_datatype">?
  • <cache?usage="read-write"/>?
  • <id?name="id"?column="TYPEID"?type="java.lang.Long">?
  • <generator?class="sequence"/>?
  • </id>?
  • <property?name="name"?column="NAME"?type="java.lang.String"/>?
  • <property?name="dbType"?column="DBTYPE"?type="java.lang.String"/>?
  • </class>?
  • </hibernate-mapping>? 关键就是这个<cache usage="read-write"/>,其有几个选择read-only,read-write,transactional,等 然后在执行查询时 注意了 ,如果是条件查询,或者返回所有结果的查询,此时session.find()方法 不会获取缓存中的数据。

    只有调用query.iterate()方法时才会调缓存的数据。

    同时 get 和 load方法 是都会查询缓存中的数据

    hibernate框架的优缺点有哪些?什么时候才用二级缓存?

    1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。

    2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。

    他很大程度的简化DAO层的编码工作 3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。

    4. hibernate的性能非常好,因为它是个轻量级框架。

    映射的灵活性很出色。

    它支持各种关系数据库,从一对一到多对多的各种复杂关系。

    hibernate 3除了一级缓存,二级缓存,还有其它的缓存吗?

    Hibernate中提供了两级Cache,第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。

    这一级别的缓存由hibernate管理的,一般情况下无需进行干预;第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或群集范围的缓存。

    这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。

    Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存。

  • LightNode(7.71美元),免认证高质量香港CN2 GIA

    LightNode是一家位于香港的VPS服务商.提供基于KVM虚拟化技术的VPS.在提供全球常见节点的同时,还具备东南亚地区、中国香港等边缘节点.满足开发者建站,游戏应用,外贸电商等应用场景的需求。新用户注册充值就送,最高可获得20美元的奖励金!成为LightNode的注册用户后,还可以获得属于自己的邀请链接。通过你的邀请链接带来的注册用户,你将直接获得该用户的消费的10%返佣,永久有效!平台目前...

    racknerd:美国大硬盘服务器(双路e5-2640v2/64g内存/256gSSD+160T SAS)$389/月

    racknerd在促销美国洛杉矶multacom数据中心的一款大硬盘服务器,用来做存储、数据备份等是非常划算的,而且线路还是针对亚洲有特别优化处理的。双路e5+64G内存,配一个256G的SSD做系统盘,160T SAS做数据盘,200T流量每个月,1Gbps带宽,5个IPv4,这一切才389美元...洛杉矶大硬盘服务器CPU:2 * e5-2640v2内存:64G(可扩展至128G,+$64)硬...

    2021年恒创科技618活动:香港/美国服务器/云服务器/高防全场3折抢购

    2021年恒创科技618活动香港美国服务器/云服务器/高防全场3折抢购,老客户续费送时长,每日限量秒杀。云服务器每款限量抢购,香港美国独服/高防每款限量5台/天,香港节点是CN2线路还不错。福利一:爆品秒杀 超低价秒杀,秒完即止;福利二:云服务器 火爆机型 3折疯抢;福利三:物理服务器 爆款直降 800元/月起;福利四:DDOS防护 超强防御仅 1750元/月。点击进入:2021年恒创科技618活...

    hibernate二级缓存为你推荐
    余额宝收益走势图余额宝七日年化收益率走势图,哪个网站天天更新?直接能看到?accesspointHP elitebook2530p 用无线路由器时 要我输入一个ralink wireless access point 什么意思信息发布管理系统信息发布系统的功能有哪些?垂直型网站水平型、垂直型、综合型电子商务网站的主要特征是什么?it人物IT人员是做什么的`广州品牌网站设计广州品牌设计公司hadoop大数据平台大数据与Hadoop之间是什么关系本地连接断开本地连接老是断开怎么解决程序文件EXE文件是什么手机证书申请手机证书怎么申请啊
    免费域名注册 长沙服务器租用 域名查询工具 域名空间购买 出租服务器 vps安全设置 GGC 美国主机论坛 godaddy优惠券 坐公交投2700元 789电视 双十一秒杀 vip域名 空间登陆首页 上海电信测速网站 外贸空间 新加坡空间 主机返佣 数据湾 windowssever2008 更多