hibernate的查询缓存和二级缓存的配合使用

我的上一篇博客Hibernate缓存体系之查询缓存(query cache),以及list和iterate方法的差别介绍了查询缓存的概念,以及list和iterate的差别。读者可能注意到:那篇博客測试的前提是,仅仅开启查询缓存,没有开启二级缓存。

通过各种情形測试,我们能够得出一个结论:仅仅开启查询缓存。不开启二级缓存是没有意义的

为什么这么说呢?上一篇博客能够看出。不开启二级缓存,iterate()方法存在N+1次数据库查询问题,list方法最多仅仅能命中id。也须要N次数据库查询,不管是哪儿种情况,查询缓存已经失去了意义。这篇博客我们开启二级缓存的情况下。将上篇博客的情况再測试下。看下会是什么效果。

hibernate4.1.6在hibernate.cfg.xml进行例如以下配置,能够开启二级缓存。

<property name="cache.use_second_level_cache">true</property>
<property name="cache.region.factory_class">org.hibernate.cache.EhCacheRegionFactory</property>

因为測试代码和数据库都和上篇博客一模一样。唯一不同就是开启了二级缓存。这里不再附代码。直接通过測试结果来分析结论。

1. 2次list()运行结果分析

testUseList()运行结果例如以下:

Hibernate:
    select
        student0_.id as id0_,
        student0_.name as name0_,
        student0_.age as age0_
    from
        Student student0_
    where
        student0_.name=‘zhangsan111‘
list语句測试query cache:[email protected][id=1, name=zhangsan111, age=18]
list语句測试query cache:[email protected][id=2, name=zhangsan111, age=18]
list语句測试query cache:[email protected][id=3, name=zhangsan111, age=18]
-------list进行第二次查询------
list语句測试query cache:[email protected][id=1, name=zhangsan111, age=18]
list语句測试query cache:[email protected][id=2, name=zhangsan111, age=18]
list语句測试query cache:[email protected][id=3, name=zhangsan111, age=18]

能够发现list()第一次发出1条sql语句。第二次查询没有訪问数据库,直接从缓存中获取的数据。在开启查询缓存和二级缓存的情况下,list将获取到的id放入查询缓存,key是sql语句。将实体对象放入二级缓存,key是实体对象的主键值。list会首先依据sql语句去查询缓存中获取id,假设没有获取到则发出1条sql查询语句,查询出全部须要的字段值。

2. 2次iterate()运行结果分析

testUseIterator()运行结果例如以下:

<span style="font-size:14px;">Hibernate:
    select
        student0_.id as col_0_0_
    from
        Student student0_
    where
        student0_.name=‘zhangsan111‘
Hibernate:
    select
        student0_.id as id0_0_,
        student0_.name as name0_0_,
        student0_.age as age0_0_
    from
        Student student0_
    where
        student0_.id=?
iterate语句測试query cache:[email protected][id=1, name=zhangsan111, age=18]
Hibernate:
    select
        student0_.id as id0_0_,
        student0_.name as name0_0_,
        student0_.age as age0_0_
    from
        Student student0_
    where
        student0_.id=?
iterate语句測试query cache:[email protected][id=2, name=zhangsan111, age=18]
Hibernate:
    select
        student0_.id as id0_0_,
        student0_.name as name0_0_,
        student0_.age as age0_0_
    from
        Student student0_
    where
        student0_.id=?
iterate语句測试query cache:[email protected][id=3, name=zhangsan111, age=18]
-------iterate进行第二次查询------
Hibernate:
    select
        student0_.id as col_0_0_
    from
        Student student0_
    where
        student0_.name=‘zhangsan111‘
iterate语句測试query cache:[email protected][id=1, name=zhangsan111, age=18]
iterate语句測试query cache:[email protected][id=2, name=zhangsan111, age=18]
iterate语句測试query cache:[email protected][id=3, name=zhangsan111, age=18]</span>

第一次iterate()查询,因为查询缓存和二级缓存中都没有数据,须要进行N+1次数据库查询;第二次查询,仅仅发出一条sql查询主键值,兴许依据主键值从二级缓存中获取具体信息。iterate方法会将获取到的实体对象存入二级缓存。至于是否会将id存入查询缓存,这里还不能确定,只是能够肯定的是。iterate不会利用查询缓存中的id值。而是每次查询都又一次使用sql查询满足条件的记录主键值。

之后再依据主键从二级缓存中查询实体对象。

3. 先iterate后list运行结果分析

testIteratorAndList1()运行结果例如以下:

<span style="font-size:14px;">Hibernate:
    select
        student0_.id as col_0_0_
    from
        Student student0_
    where
        student0_.name=‘zhangsan111‘
Hibernate:
    select
        student0_.id as id0_0_,
        student0_.name as name0_0_,
        student0_.age as age0_0_
    from
        Student student0_
    where
        student0_.id=?
iterate语句測试query cache:[email protected][id=1, name=zhangsan111, age=18]
Hibernate:
    select
        student0_.id as id0_0_,
        student0_.name as name0_0_,
        student0_.age as age0_0_
    from
        Student student0_
    where
        student0_.id=?
iterate语句測试query cache:[email protected][id=2, name=zhangsan111, age=18]
Hibernate:
    select
        student0_.id as id0_0_,
        student0_.name as name0_0_,
        student0_.age as age0_0_
    from
        Student student0_
    where
        student0_.id=?
iterate语句測试query cache:[email protected][id=3, name=zhangsan111, age=18]
-------第一次使用iterate,第二次使用list查询------
Hibernate:
    select
        student0_.id as id0_,
        student0_.name as name0_,
        student0_.age as age0_
    from
        Student student0_
    where
        student0_.name=‘zhangsan111‘
list语句測试query cache:[email protected][id=1, name=zhangsan111, age=18]
list语句測试query cache:[email protected][id=2, name=zhangsan111, age=18]
list语句測试query cache:[email protected][id=3, name=zhangsan111, age=18]</span>

这里能够看出,iterate的缓存信息对于list是没有帮助的。list会发出1条sql。从数据库中查询全部须要的字段值。这里能够看出:iterate方法不会将主键值放到查询缓存中,由于假设放入查询缓存的话。这里的list是没有必要再发出sql查询的。

4. 先listiterate运行结果分析

testIteratorAndList2()运行结果例如以下:

<span style="font-size:14px;">Hibernate:
    select
        student0_.id as id0_,
        student0_.name as name0_,
        student0_.age as age0_
    from
        Student student0_
    where
        student0_.name=‘zhangsan111‘
list语句測试query cache:[email protected][id=1, name=zhangsan111, age=18]
list语句測试query cache:[email protected][id=2, name=zhangsan111, age=18]
list语句測试query cache:[email protected][id=3, name=zhangsan111, age=18]
-------第一次使用list,第二次使用iterate查询------
Hibernate:
    select
        student0_.id as col_0_0_
    from
        Student student0_
    where
        student0_.name=‘zhangsan111‘
iterate语句測试query cache:[email protected][id=1, name=zhangsan111, age=18]
iterate语句測试query cache:[email protected][id=2, name=zhangsan111, age=18]
iterate语句測试query cache:[email protected][id=3, name=zhangsan111, age=18]</span>

这里可以得出的结论,跟2次list()查询几乎相同。

唯一的区别是:iterate每次查询都会发出查询实体对象id的sql语句。

5. 总结

通过开启查询缓存和二级缓存,相同的sql查询可以直接使用查询缓存中的id和二级缓存中的实体对象,可以有效的降低反复的数据库查询,可以提高查询效率。也就是说:同一时候开启查询缓存和二级缓存是有意义的。也是实际使用hibernate的最佳配置。

进一步的。我们也能够看出list和iterate方法的差别。list()会将实体对象的id放入查询缓存,将实体对象本身放入二级缓存。iterate不会将实体对象的id放入查询缓存。可是会将实体对象本身存入二级缓存。

假设第二次查询可以命中的情况下:list全然不须要查询数据库,可以先从查询缓存中获取到id。再从二级缓存中获取实体对象。iterate一定会发出一条查id的sql,然后去二级缓存中获取实体对象。

至此hibernate的二级缓存、查询缓存的关系已经讲完。list和iterate差别也已经測试出。

希望能对大家有帮助,假设错误。欢迎大牛们指正。

时间: 2024-07-28 20:35:37

hibernate的查询缓存和二级缓存的配合使用的相关文章

[原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Hibernate一级缓存、二级缓存以及查询缓存的关系

转载自http://blog.csdn.net/maoyeqiu/article/details/50209893 前两天总结了一下二级缓存和查询缓存的关系,但是又有一个新的问题,就是查询缓存缓存到二级缓存的数据,在第三次(第一次缓存中没有数据,查询数据库将对应的ID值存入到二级缓存中去,第二次如果是同一个Session那么将会把数据一级缓存中的数据返回,如果不是同一个Session而是同一个sessionfactory,那么将会把二级缓存中的数据返回,同时将数据放入到一级缓存中去)获取的时候,

hibernate回顾之缓存机制-一级缓存、二级缓存、查询缓存

在介绍hibernate的缓存机制前,我们先了解一下什么是缓存: 缓存(Cache): 计算机领域非常通用的概念.里面放东西,说白了缓存就是一个集合.它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能.缓存中的数据是数据存储源中数据的拷贝并且缓存的物理介质通常是内存. 了解jdbc的人都知道,当需要连接数据库时,一般都会做一个连接池,那么连接池和缓存有什么区别呢? 相同点:两者都可以是在内存里,实现时一样的

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

一级缓存 (必定存在)  session里共享缓存,伴随session的生命周期存在和消亡: 1. load查询实体支持一级缓存 2. get查询实体对象也支持 3. save保存的实体对象会缓存在一级缓存 4. clear evict会清除session缓存 5. save巨大数据,每20个数据,一般flush执行sql将数据持久化然后clear缓存,防止内存溢出,save放最后. 6. iterate使用一级缓存(creatQuery中的查询实体对象list会使用一级缓存,查询对象实体属性不

hibernate 一级缓存,二级缓存,查询缓存

1.一级缓存是session级的缓存,session结束即事务提交,session关闭,缓存清除.效果不大 get方式:一个session内,第二次查询不连数据库.适用于一级缓存 load方式:懒加载查询(查询时不执行sql,使用结果时才会执行sql),第二次查询不连数据库.适用于一级缓存 createQuery(hql).list():查询了整个list,第一次调用list()时,执行sql.第二次查询时,又执行了sql,说明不使用一级缓存.也就是不使用二级缓存    createQuery(

Hibernate一级缓存和二级缓存深度比较

1.什么是缓存 缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据. 缓存的介质一般是内存,所以读写速度很快.但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质.缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期. Hibernate的一级缓存是内置的,不能被卸载. Hiberna

【转】hibernate缓存:一级缓存和二级缓存

什么是缓存? 缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器,其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能.Hibernate在进行读取数据的时候,根据缓存机制在相应的缓存中查询,如果在缓存中找到了需要的数据(我们把这称做"缓存命 中"),则就直接把命中的数据作为结果加以利用,避免了大量发送SQL语句到数据库查询的性能损耗. 缓存策略提供商 提供了HashTable缓存,EHCache,OSCache,SwarmCac

Hibernate一级缓存和二级缓存具体解释

一.一级缓存二级缓存的概念解释 (1)一级缓存就是Session级别的缓存,一个Session做了一个查询操作,它会把这个操作的结果放在一级缓存中.假设短时间内这个 session(一定要同一个session)又做了同一个操作.那么hibernate直接从一级缓存中拿,而不会再去连数据库,取数据: (2)二级缓存就是SessionFactory级别的缓存,顾名思义.就是查询的时候会把查询结果缓存到二级缓存中,假设同一个sessionFactory 创建的某个session运行了同样的操作,hib

hibernate缓存机制(二级缓存)

一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据. 二.what(Hibernate缓存原理是怎样的?)Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存. 1.Hibernate一级缓存又称为“Session的