get()和load()方法既可以向一级缓存区放数据,也可以向二级缓存区放数据。这是查询一个的情况。要是查询所有呢?注意,

// 查询所有.Query接口的list()方法.
// list()方法会向二级缓存中放数据,但是不会使用二级缓存中的数据.

//list()方法没有使用二级缓存的数据.

没有发生SQL,证明肯定是从一级缓存或者是二级缓存获取的数据.一级缓存没有,那肯定是从二级缓存获取的.有人说那这list()方法的效率就比较低了。一级缓存经常使用list(),但是有了二级缓存如果你想查询所有,可以用另外一个方法。

如果没有二级缓存,不建议使用iterate()(因为效率会比较低),迭代器的方法。


// iterate()方法可以查询所有信息.
// iterate方法会发送N+1条SQL查询.但是会使用二级缓存的数据

  // N+1条SQL去查询.

iterate()的效果:

Hibernate:
select
customer0_.cid as col_0_0_
from
customer customer0_
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.version as version0_0_,
customer0_.cname as cname0_0_,
customer0_.age as age0_0_
from
customer customer0_
where
customer0_.cid=?
Customer [cid=1, cname=小金, age=23, ver=0]
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.version as version0_0_,
customer0_.cname as cname0_0_,
customer0_.age as age0_0_
from
customer customer0_
where
customer0_.cid=?
Customer [cid=2, cname=小明, age=32, ver=0]
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.version as version0_0_,
customer0_.cname as cname0_0_,
customer0_.age as age0_0_
from
customer customer0_
where
customer0_.cid=?
Customer [cid=3, cname=沈明贞, age=28, ver=1]
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.version as version0_0_,
customer0_.cname as cname0_0_,
customer0_.age as age0_0_
from
customer customer0_
where
customer0_.cid=?
Customer [cid=4, cname=张三, age=28, ver=0]
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.version as version0_0_,
customer0_.cname as cname0_0_,
customer0_.age as age0_0_
from
customer customer0_
where
customer0_.cid=?
Customer [cid=5, cname=张三, age=28, ver=0]

如果没有二级缓存,iterate()方法效率比较低。因为执行Iterator<Customer> iterator = session.createQuery("from Customer").iterate();调用iterate()只查询所有客户的id。当你每次迭代的时候它才会根据你每个客户的id去查询客户的信息。所以iterate()是一个N+1条SQL去查询。你有N条记录,它会发N+1条SQL去查询。第一条是查询所有的id,然后再根据id逐一检索。所以这个方法效率比较低。list()方法效率高,直接全部都查出来了。

但是list()有了二级缓存,效率就比不上iterate()。因为iterate()可以使用二级缓存的数据。

开放/配置二级缓存

<!-- Hibernate中开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 配置二级缓存的提供商 -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

<!-- 配置哪些类使用二级缓存 -->
<class-cache usage="read-write" class="cn.itcast.hibernate3.demo1.Customer"/>
<!--查询订单的类缓存区-->

<class-cache usage="read-write" class="cn.itcast.hibernate3.demo1.Order"/>

之后,iterate()的效果:

Hibernate:
select
customer0_.cid as col_0_0_
from
customer customer0_
Customer [cid=1, cname=小金, age=23, ver=0]
Customer [cid=2, cname=小明, age=32, ver=0]
Customer [cid=3, cname=沈明贞, age=28, ver=1]
Customer [cid=4, cname=张三, age=28, ver=0]
Customer [cid=5, cname=张三, age=28, ver=0]

还是会发送SQL语句查询所有客户的id,但是在根据客户的id检索每一条记录的时候就直接打印了,而没有再发生SQL去查询。所以iterate()是可以使用二级缓存的。


 结论:

在查询所有的时候,如果有二级缓存,使用iterate(),如果没有二级缓存,使用list(). 


    @SuppressWarnings("unchecked")
@Test
// iterate()方法可以查询所有信息.
// iterate方法会发送N+1条SQL查询.但是会使用二级缓存的数据
public void demo5(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // N+1条SQL去查询.
Iterator<Customer> iterator = session.createQuery("from Customer").iterate();
while(iterator.hasNext()){
Customer customer = iterator.next();
System.out.println(customer);
} tx.commit(); session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction(); iterator = session.createQuery("from Customer").iterate();
while(iterator.hasNext()){
Customer customer = iterator.next();
System.out.println(customer);
} tx.commit();
} @SuppressWarnings("unchecked")
@Test
// 查询所有.Query接口的list()方法.
// list()方法会向二级缓存中放数据,但是不会使用二级缓存中的数据.
public void demo4(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 查询所有客户:
// list方法会向二级缓存中放入数据的.
List<Customer> list = session.createQuery("from Customer").list();
for (Customer customer : list) {
System.out.println(customer.getCname());
}
tx.commit(); session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction(); Customer customer = (Customer) session.get(Customer.class, 1);// 没有发生SQL ,从二级缓存获取的数据.
//list()方法没有使用二级缓存的数据.
/* list = session.createQuery("from Customer").list();
for (Customer customer : list) {
System.out.println(customer.getCname());
}*/ tx.commit();
}

day37 04-Hibernate二级缓存:list和iterate方法比较的更多相关文章

  1. Hibernate 二级缓存 总结整理(转)

    和<Hibernate 关系映射 收集.总结整理> 一样,本篇文章也是我很早之前收集.总结整理的,在此也发上来 希望对大家有用.因为是很早之前写的,不当之处请指正. 1.缓存:缓存是什么, ...

  2. hibernate二级缓存demo2

    @Test public void hello3(){ Session session=sessionFactory.openSession(); List list = session.create ...

  3. Hibernate ——二级缓存

    一.Hibernate 二级缓存 1.Hibernate 二级缓存是 SessionFactory 级别的缓存. 2.二级缓存分为两类: (1)Hibernate内置二级缓存 (2)外置缓存,可配置的 ...

  4. 配置Hibernate二级缓存时,不能初始化RegionFactory的解决办法

    配置Hibernate 二级缓存时,出现以下bug提示: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder&quo ...

  5. 配置Hibernate二级缓存步骤

    配置Hibernate二级缓存步骤: 加入二级缓存的jar包及配置文件 jar包位置:hibernate-release-4.1.8.Final\lib\optional\ehcache下所有jar包 ...

  6. Hibernate(十六):Hibernate二级缓存

    Hibernate缓存 缓存(Cache):计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如磁盘上的文件或者数据库)之间,起作用是降低应用程序直接读取永久性数据存储源的频率,从而提高应用 ...

  7. hibernate二级缓存整合

    <?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http:// ...

  8. ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存

    ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate  : Hibernate是一个持久层框架,经常访问物理数据库 ...

  9. spring boot集成ehcache 2.x 用于hibernate二级缓存

    https://www.jianshu.com/p/87b2c309b776 本文将介绍如何在spring boot中集成ehcache作为hibernate的二级缓存.各个框架版本如下 spring ...

  10. js相关(easyUI),触发器,ant,jbpm,hibernate二级缓存ehcache,Javamail,Lucene,jqplot,WebService,regex,struts2,oracle表空间

    *********************************************js相关********************************************* // 在指 ...

随机推荐

  1. C++ Builder VCL库函数简介

    C++ Builder VCL库函数简介 2002-07-05· · ··C++builder资源中心 1 2 3 下一页 一.BORLAND C++ BUILDER VCL的内存管理函数 1. Al ...

  2. win10系统,vbox下安装centos6/7,挂载实现目录共享

    用下载好的iso文件,新建虚拟机(所有步骤默认下一步即可). 我用的centos版本:CentOS-7-x86_64-Minimal-1908.iso ISO下载地址 设置虚拟机(指定好镜像后,先不要 ...

  3. PHPstorm同步服务器代码的缺点---命名空间undefined

      在把一个服务器的代码同步到phpstorm下开发的时候,发现新建的命名空间代码都失效了,然而换到 https://blog.csdn.net/afraid_to_have/article/deta ...

  4. EF(Entity Framwork)结构

    初次接触EF,看了一些资料,将自己对EF结构的理解记录如下: EF的核心是EDM----实体数据模型(.edmx).它由三部分组成:概念模型(.csdl文件).存储模型(.ssdl文件).映射规范(. ...

  5. Android之FrameLayout帧布局

    1.简介 这个布局直接在屏幕上开辟出一块空白的区域,当我们往里面添加控件的时候,会默认把他们放到这块区域的左上角; 帧布局的大小由控件中最大的子控件决定,如果控件的大小一样大的话,那么同一时刻就只能看 ...

  6. 反编译之jadx工具

    1.jadx是个开源 https://github.com/skylot/jadx 2.下载后cd到文件的根目录 然后输入命令 ./gradlew dist 之后会出现build文件进入/build/ ...

  7. WebSocket实践

    基本弄清楚了WebSocket的来龙去脉后,开始了实现WebSocket技术的探索. 看过一篇文章,测试了八种WebSocket框架性能,得以了解到实现WebSocket技术的框架有: Netty.U ...

  8. <meta>标记

    <meta>的主要作用: 是提供网页的元素信息 属性: http-equiv: 功能: 默认http协议文件头信息,当信息从服务器端传到客户端时,让浏览器正确的是显示, http_equi ...

  9. Cocos2d-x 创建工程python脚本

    @echo offset /p projectName=请输入项目名称:if "%projectName%"=="" goto inputErrorset /p ...

  10. python内置类型详细解释

    文章编写借鉴于内置类型 - Python 3.7.3 文档,主要用于自己学习和记录 python主要内置类型包括数字.序列.映射.类.实例和异常 有些多项集类是可变的.它们用于添加.移除或重排其成员的 ...