- 浏览: 449965 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
g_man1990:
update config 不成功啊
build-helper-maven-plugin 配置多 source resource 文件 -
netwelfare:
文章很详细,就是太长了,读起来有点困难,倒不如写精练点,像这篇 ...
Java 基本类型 -
huyuancai1010:
function commitForm() {
var ...
加时间戳或者随机数去除js缓存 -
Smile__:
不过这个东西以前还真没研究过 。
hibernate.jdbc.fetch_size 和 hibernate.jdbc.batch_size -
Smile__:
想不到你也是北大青鸟的 。哈
hibernate.jdbc.fetch_size 和 hibernate.jdbc.batch_size
自己测试的一些结果 , 可能不是很正确,往大家给给意见:
二级缓存和查询缓存都相当于一个map。
二级缓存缓存的key为id,value为实体对象。一般load(),iterate()使用到二级缓存,list()需要结合查询缓存使用。iterate()和list()区别如下:
iterate()不需要开启查询缓存,它首先发出一个sql如”select s.id from Student s”去数据库把id属性列表取出来,然后再根据id列表一个一个load(),如果缓存有从缓存取,如果缓存没有就从数据库取:select s.id,s.name,s.classid from Student s where s.id=?,取出后再存入二级缓存。Iterate总会发出取id列表的语句。
List()需要开启查询缓存,它首先发出一个sql如”select s.id,s.name,s.classid from Student s…”去数据库取出所有相关实体,并将这些实体存入二级缓存,将此sql语句及一些相关信息作为key,id列表作为值,第二次查询这条语句时就会去根据sql语句及相关信息去key里找,如果有就会把id列表取出一个一个load(),接下来就和iterate一样了。List一般只有第一次发发出取实体列表的语句,以后的id列表就会去查询缓存取id列表,不会再发出sql语句。
前提:执行同一hql语句,如:select s from Student s
1.关闭查询缓存,开启二级缓存时:
第二次查询属性时iterate只会发出获取id列表的sql,list会发出和第一次一样的请求实体的sql。
2.开启查询缓存,开启二级缓存
第二次查询属性时iterate只会发出获取id列表的sql,list不发sql。
以上说明iterate只和二级缓存有关,list和二级缓存和查询缓存都有关。
list 不会使用二级缓存,但是会填充二级缓存,还会使用查询缓存
out join 使用查询缓存二级缓存
1.Criteria.list 会 会
2.Query.list 不会 会
3.Query.iterate 会 会
4.A先Criteria.list 会
B后Query.list 不会 不会使用A的结果缓存
5.A先Query.list 不会
B后Criteria.list 会 不会使用A的结果缓存
6.A先Query.iterate 会
B后Query.list 不会 不会使用A的结果缓存
7.A先Query.list 不会
B后Query.iterate 不会 使用A的结果缓存
8.A先Criteria.list 会
B后Query.iterate 使用A的结果缓存
9.A先Query.iterate 会
B后Criteria.list 会 不会使用A的结果缓存
如果开启了二级缓存,hibernate在执行任何一次查询的之后,都会把得到的结果集放到缓存中,缓存结构可以看作是一个hash table,key是数据库记录的id,value是id对应的pojo对象。当用户根据id查询对象的时候(load、iterator方法),会首先在缓存中查找,如果没有找到再发起数据库查询。但是如果使用hql发起查询(find, query方法)则不会利用二级缓存,而是直接从数据库获得数据,但是它会把得到的数据放到二级缓存备用。也就是说,基于hql的查询,对二级缓存是只写不读的。
针对二级缓存的工作原理,采用iterator取代list来提高二级缓存命中率的想法是不可行的。Iterator的工作方式是根据检索条件从数据库中选取所有目标数据的id,然后用这些id一个一个的到二级缓存里面做检索,如果找到就直接加载,找不到就向数据库做查询。因此假如iterator检索100条数据的话,最好情况是100%全部命中,最坏情况是0%命中,执行101条sql把所有数据选出来。而list虽然不利用缓存,但是它只会发起1条sql取得所有数据。在合理利用分页查询的情况下,list整体效率高于iterator。
二级缓存的失效机制由hibernate控制,当某条数据被修改之后,hibernate会根据它的id去做缓存失效操作。基于此机制,如果数据表不是被hibernate独占(比如同时使用JDBC或者ado等),那么二级缓存无法得到有效控制。
由于hibernate的缓存接口很灵活,cache provider可以方便的切换,因此支持cluster环境不是大问题,通过使用swarmcache、jboss cache等支持分布式的缓存方案,可以实现。但是问题在于:
1、 分布式缓存本身成本偏高(比如使用同步复制模式的jboss cache)
2、 分布式环境通常对事务控制有较高要求,而目前的开源缓存方案对事务缓存(transaction cache)支持得不够好。当jta事务发生会滚,缓存的最后更新结果很难预料。这一点会带来很大的部署成本,甚至得不偿失。
结论:不应把hibernate二级缓存作为优化的主要手段,一般情况下建议不要使用。
原因如下:
1、 由于hibernate批量操作的性能不如sql,而且为了兼容1.0的dao类,所以项目中有保留了sql操作。哪些数据表是单纯被hibernate独占无法统计,而且随着将来业务的发展可能会有很大变数。因此不宜采用二级缓存。
2、 针对系统业务来说,基于id检索的二级缓存命中率极为有限,hql被大量采用,二级缓存对性能的提升很有限。
3、 hibernate 3.0在做批量修改、批量更新的时候,是不会同步更新二级缓存的,该问题在hibernate 3.2中是否仍然存在尚不确定。
二、hibernate的查询缓存
查询缓存的实现机制与二级缓存基本一致,最大的差异在于放入缓存中的key是查询的语句,value是查询之后得到的结果集的id列表。表面看来这样的方案似乎能解决hql利用缓存的问题,但是需要注意的是,构成key的是:hql生成的sql、sql的参数、排序、分页信息等。也就是说如果你的hql有小小的差异,比如第一条hql取1-50条数据,第二条hql取20-60条数据,那么hibernate会认为这是两个完全不同的key,无法重复利用缓存。因此利用率也不高。
另外一个需要注意的问题是,查询缓存和二级缓存是有关联关系的,他们不是完全独立的两套东西。假如一个查询条件hql_1,第一次被执行的时候,它会从数据库取得数据,然后把查询条件作为key,把返回数据的所有id列表作为value(请注意仅仅是id)放到查询缓存中,同时整个结果集放到class缓存(也就是二级缓存),key是id,value是pojo对象。当你再次执行hql_1,它会从缓存中得到id列表,然后根据这些列表一个一个的到class缓存里面去找pojo对象,如果找不到就向数据库发起查询。也就是说,如果二级缓存配置了超时时间(或者发呆时间),就有可能出现查询缓存命中了,获得了id列表,但是class里面相应的pojo已经因为超时(或发呆)被失效,hibernate就会根据id清单,一个一个的去向数据库查询,有多少个id,就执行多少个sql。该情况将导致性能下降严重。
查询缓存的失效机制也由hibernate控制,数据进入缓存时会有一个timestamp,它和数据表的timestamp对应。当hibernate环境内发生save、update等操作时,会更新被操作数据表的timestamp。用户在获取缓存的时候,一旦命中就会检查它的timestamp是否和数据表的timestamp匹配,如果不,缓存会被失效。因此查询缓存的失效控制是以数据表为粒度的,只要数据表中任何一条记录发生一点修改,整个表相关的所有查询缓存就都无效了。因此查询缓存的命中率可能会很低。
结论:不应把hibernate二级缓存作为优化的主要手段,一般情况下建议不要使用。
原因如下:
1、 项目上层业务中检索条件都比较复杂,尤其是涉及多表操作的地方。很少出现重复执行一个排序、分页、参数一致的查询,因此命中率很难提高。
2、 查询缓存必须配合二级缓存一起使用,否则极易出现1+N的情况,否则性能不升反降
3、 使用查询缓存必须在执行查询之前显示调用Query.setCacheable(true)才能激活缓存,这势必会对已有的hibernate封装类带来问题。
总结
详细分析hibernate的二级缓存和查询缓存之后,在底层使用通用缓存方案的想法基本上是不可取的。比较好的做法是在高层次中(业务逻辑层面),针对具体的业务逻辑状况手动使用数据缓存,不仅可以完全控制缓存的生命周期,还可以针对业务具体调整缓存方案提交命中率。Cluster中的缓存同步可以完全交给缓存本身的同步机制来完成。比如开源缓存swarmcache采用invalidate的机制,可以根据用户指定的策略,在需要的时候向网络中的其他swarmcache节点发送失效消息,建议采用。
评论
发表评论
-
Hibernate search
2011-02-21 14:44 3427Hibernate Search是Hibernate的子项目, ... -
SimpleJdbc
2010-05-26 17:21 1932SimpleJdbcInsert类和SimpleJdbcCal ... -
Hibernate 注解 annotation
2010-05-05 20:37 15036一、 实体 Bean 每个持久化POJO类都是一个实体Bea ... -
Hibernate 拦截器 和 监听器
2009-11-25 11:29 1885拦截器(Intercept):顾名思义,拦截操作,也就是在Hi ... -
hibernate.jdbc.fetch_size 和 hibernate.jdbc.batch_size
2009-11-17 17:32 19933hibernate.jdbc.fetch_size 50 h ... -
get 会使用二级缓存
2009-09-03 17:17 1456经常看到session.get()和session.load( ... -
Query.list 与 Query.iterate 的区别
2009-09-03 17:08 1950list: 结果存入缓存,但不从缓存里面取;查询时属性连同id ... -
Jdbc 与 Jta 事务
2009-08-26 14:35 2672hibernate的两种事务管理jdbc 和jta方式。下边说 ... -
Hibernate Session Flush
2009-08-14 11:34 8630session flush在commit之前默 ... -
GenericSpringDAO<T extends ...>
2009-08-03 10:06 1530import java.io.Serializable;imp ... -
Hibernate Annotation driven equals and hashCode
2009-07-03 16:56 1481The following implementation of ... -
hibernate cascade inverse
2009-06-28 19:43 1156这两个属性都用于一多 ... -
Hibernate Criteria
2009-06-19 11:15 1071Hibernate 设计了 CriteriaSpec ... -
Hibernate的Criteria 简单用法
2009-05-26 16:52 1812在hibernate的Session里面使用createCri ... -
Hibernate中Criteria的完整用法
2009-05-26 16:46 625Criteria 在查询方法设计上可以灵活的根据 Criter ... -
Hibernate 的连接池属性简介
2009-05-07 11:30 1661Hibernate配置属性 ... -
Hibernate Inverse
2009-04-23 17:15 1284一、Inverse是hibernate双向关系中的基本概念。i ... -
hibernate的hibernate.hbm2ddl.auto属性
2009-01-06 16:33 2383<property name="hibern ... -
hibernate主键常用方式
2009-01-06 16:32 10521) assigned 主键由外部程序负责生成,无需Hibe ...
相关推荐
**hibernate一级缓存、二级缓存和查询缓存** 在Java的持久化框架Hibernate中,缓存机制是提高应用程序性能的关键要素。缓存能够减少数据库的访问次数,提高数据读取速度,并且在一定程度上降低了系统的负载。本文将...
总结来说,Hibernate 的一级缓存和二级缓存都是为了提高数据访问效率,但它们在范围和并发控制方面有所不同。一级缓存是事务级别的,保证了数据的强一致性,而二级缓存提供了更多的灵活性,可以跨事务共享,但需要...
Hibernate二级缓存是一种提高应用程序性能的技术,它将数据存储在SessionFactory级别的缓存中,使得数据可以在不同的Session之间共享。这与一级缓存(Session级别)不同,一级缓存仅存在于单个Session生命周期内,当...
在这个"hibernate二级缓存实例"中,我们将深入探讨二级缓存的原理、配置以及在实际项目中的应用。 首先,我们需要了解一级缓存和二级缓存的区别。一级缓存是Session级别的,每个Session都有自己的一级缓存,用于...
在Hibernate中,二级缓存可以使用不同的提供商,例如Ehcache和OSCache。配置Ehcache作为二级缓存提供商,需要在Hibernate的配置文件中设置`hibernate.cache.provider_class`为`...
本文将深入探讨Hibernate的一级缓存、二级缓存以及查询缓存,通过具体的实例来阐述它们的工作原理和使用方法。 首先,我们从一级缓存开始。一级缓存是Hibernate默认提供的缓存,它是每个Session级别的,也被称为...
**二、Hibernate二级缓存** 二级缓存是SessionFactory级别的,跨越了多个Session,可以被多个线程共享。它通常由第三方插件如EhCache、Infinispan等提供。二级缓存分为以下几种类型: 1. **集合缓存**:用于存储...
综上所述,通过学习`hibernate二级缓存示例源码`,我们可以了解到如何在实际项目中配置和使用Hibernate二级缓存,从而提升系统的性能。在实际应用中,应结合具体场景选择合适的缓存策略,以达到最佳的性能优化效果。
综上所述,Hibernate二级缓存配合Ehcache使用,能够有效提升Java应用的性能,降低数据库压力,同时Ehcache提供的丰富功能和灵活性使其成为Java缓存领域中的热门选择。在实际项目中,正确配置和使用Ehcache,能够为...
在 Hibernate 中,二级缓存和查询缓存是提高应用性能的重要机制。下面将详细介绍如何开启并理解这两个缓存机制。 ### 1. 一级缓存与二级缓存 #### 1.1 一级缓存 一级缓存是 Hibernate 内置的 Session 缓存,它是每...
`hibernate.cache.use_query_cache`和`hibernate.cache.use_second_level_cache`分别开启了查询缓存和二级缓存。最后,通过`class-cache`元素配置了`EntityClass`的缓存策略,这里使用了"read-write",表示读写操作...
Hibernate 一级缓存和二级缓存的区别
Hibernate 二级缓存
二级缓存是 Hibernate 缓存策略的一部分,它在应用程序的多个会话之间共享数据,进一步优化了数据库访问效率。 二级缓存分为以下关键知识点: 1. **一级缓存与二级缓存的区别**: - 一级缓存:每个 Hibernate ...
在处理大数据量或高并发的场景下,为了提高性能和减少数据库负载,Hibernate 提供了二级缓存机制。本文将深入探讨Hibernate的二级缓存,并结合相关源码进行解析。 ### 一、一级缓存与二级缓存 1. **一级缓存...
本篇将深入探讨Hibernate的一级缓存和二级缓存,以及查询缓存的配置和使用。 ### 一级缓存 一级缓存是Hibernate默认提供的缓存,它是Session级别的,每个Hibernate Session都有一个私有的、本地的一级缓存。当我们...
通过以上步骤,我们就成功地在Spring Boot 2.1.4.RELEASE项目中配置了使用Redis作为Hibernate二级缓存的环境。这将显著提升数据库查询效率,减少对数据库的压力,尤其在高并发场景下,效果尤为明显。记得在实际生产...
本文将详细探讨如何在Spring集成的Hibernate环境中配置二级缓存,以及其背后的原理和实践。 首先,我们需要了解什么是二级缓存。在Hibernate中,一级缓存是每个Session内部的缓存,它自动管理实体的状态,当一个...
二级缓存的使用可以显著提升系统性能,特别是在频繁查询相同数据的情况下。然而,需要注意的是,虽然缓存可以提高效率,但也要考虑数据的一致性和并发控制问题,避免出现脏读、不可重复读等问题。因此,在实际应用中...