Hibernate之list和iterator
两者都是根据指定条件查询并返回符合查询的条件的实体对象;
看下session.createQuery().list():
- List<TUser> users = session.createQuery(hql).list();
- int len = users.size();
- for (int i = 0; i < len; i++) {
- TUser user = users.get(i);
- System.out.println("User name:"+user.getName());
- }
<strong><span style="font-size:18px;color:#000000;"> List<TUser> users = session.createQuery(hql).list();
int len = users.size();
for (int i = 0; i < len; i++) {
TUser user = users.get(i);
System.out.println("User name:"+user.getName());
}</span></strong>
在控制台上只会输出:
- Hibernate: select tuser0_.userid as userid0_, tuser0_.name as name0_,tuser0_.age as age0_, tuser0_.info as info0_ from t_user tuser0_ where tuser0_.age>316
<strong><span style="font-size:18px;color:#000000;">Hibernate: select tuser0_.userid as userid0_, tuser0_.name as name0_,tuser0_.age as age0_, tuser0_.info as info0_ from t_user tuser0_ where tuser0_.age>316
</span></strong>
显示的结果为:
- User name:keith 299
<strong><span style="font-size:18px;color:#000000;">User name:keith 299</span></strong>
在看下session.createQuery().iterate():
- Iterator it = session.createQuery(hql).iterate();
- while (it.hasNext()) {
- TUser users = (TUser) it.next();
- System.out.println("user Name:"+users.getName());
- }
<strong><span style="font-size:18px;color:#000000;"> Iterator it = session.createQuery(hql).iterate();
while (it.hasNext()) {
TUser users = (TUser) it.next();
System.out.println("user Name:"+users.getName());
}</span></strong>
看下控制台上的输出:
- Hibernate: select tuser0_.userid as col_0_0_ from t_user tuser0_ where tuser0_.age>316
- Hibernate: select tuser0_.userid as userid0_0_,tuser0_.name as name0_0_, tuser0_.age as age0_0_,tuser0_.info as info0_0_ from t_user tuser0_ where tuser0_.userid=?
<strong><span style="font-size:18px;color:#000000;">Hibernate: select tuser0_.userid as col_0_0_ from t_user tuser0_ where tuser0_.age>316
Hibernate: select tuser0_.userid as userid0_0_,tuser0_.name as name0_0_, tuser0_.age as age0_0_,tuser0_.info as info0_0_ from t_user tuser0_ where tuser0_.userid=?</span></strong>
所显示的结果为:
- user Name:keith 299
<strong><span style="font-size:18px;color:#000000;">user Name:keith 299</span></strong>
两者相比较,list()只发一条语句将符合条件的数据全部查出,而iterator()却现将id查出来,然后根据id再将符合条件的数据查出,这就构成了N+1的问题;既然list更高效,为什么hibernate还将iterator存在呢?
这个问题与Hibernate缓存机制密切相关,我们将两种方法写在一起:
- List<TUser> users = session.createQuery(hql).list();
- int len = users.size();
- for (int i = 0; i < len; i++) {
- TUser user = users.get(i);
- System.out.println("user Name:"+user.getName());
- }
- System.out.println("\n query by list is Over,and query by iterator is start...");
- Iterator it = session.createQuery(hql).iterate();
- while (it.hasNext()) {
- TUser user = (TUser) it.next();
- System.out.println("users name:"+user.getName());
- }
<strong><span style="font-size:18px;color:#000000;"> List<TUser> users = session.createQuery(hql).list();
int len = users.size();
for (int i = 0; i < len; i++) {
TUser user = users.get(i);
System.out.println("user Name:"+user.getName());
} System.out.println("\n query by list is Over,and query by iterator is start..."); Iterator it = session.createQuery(hql).iterate(); while (it.hasNext()) {
TUser user = (TUser) it.next();
System.out.println("users name:"+user.getName());
}</span></strong>
看下控制台的输出:
- Hibernate: select tuser0_.userid as userid0_,tuser0_.name as name0_,tuser0_.age as age0_,tuser0_.info as info0_ from t_user tuser0_ where tuser0_.age>316
- user Name:keith 299
- query by list is Over,and query by iterator is start...
- Hibernate: select tuser0_.userid as col_0_0_ from t_user tuser0_ where tuser0_.age>316
- users name:keith 299
<strong><span style="font-size:18px;color:#000000;">Hibernate: select tuser0_.userid as userid0_,tuser0_.name as name0_,tuser0_.age as age0_,tuser0_.info as info0_ from t_user tuser0_ where tuser0_.age>316 user Name:keith 299 query by list is Over,and query by iterator is start... Hibernate: select tuser0_.userid as col_0_0_ from t_user tuser0_ where tuser0_.age>316 users name:keith 299</span></strong>
只是将之前的list()和iterator()放在一起使用,这时的iterator只执行了一条SQL;其中的差异在于hibernate的缓存机制;
list()方法将执行Select SQL从数据库中获取所有符合满足条件的记录并构造相应的实体对象,实体对象构建完毕后,就将其纳入缓存;
这样等到iterator()执行时,首先会执行一条SQL来查询符合条件数据的id,随即,iterator方法首先在本地缓存内根据id查找对应的实体对象是否存在,如果缓存中已经存在对应的数据,则直接以此数据对象作为查询结果;如果没有找到,则再次执行Select语句获得对应数据库中的表记录(如果iterator在数据库中查到并构建了完整的数据对象,也会将其纳入缓存中);
在上面这个实例中,list()将读取的数据放入缓存中,iterator()直接可以用于是出现了以上的结果;
当我们再次执行上面的程序,发现结果还是一样的;list()并没有去读取它自己放进缓存的数据,因为当我们list()查询完后,即使缓存中有一些符合条件的数据,但是我们也无法保证这些数据就是合法的,如果更改下条件,将大于316改成300;那么缓存中的数据只满足大于316不会满足大于300;所有list()方法还是需要执行一次Select SQL来保证结果的完整性;得出结论:list()实际上无法利用缓存,它对缓存只写不读,而iterator()可以充分利用缓存,如果目标数据只读或者读取相当频繁,可以使用iterator()来减少性能上的消耗;
但是会出现这样一个问题,如果是海量数据怎么办?如果超过10万条记录的话,会有很大的可能出发OutOfMemoryError;导致系统异常;那么就用iterator()和evict()来解决吧!将内存消耗保持在可以接受的范围内;比如:
- Iterator it = session.createQuery(hql).iterate();
- while (it.hasNext()) {
- TUser users = (TUser) it.next();
- //在一级缓存中清理
- session.evict(users);
- //在二级缓存中清理,二级缓存可以设定
- SessionFactory.evict(TUser.class, users.getUserid());
- System.out.println("user Name:"+users.getName());
- }
<strong><span style="font-size:18px;color:#000000;"> Iterator it = session.createQuery(hql).iterate();
while (it.hasNext()) {
TUser users = (TUser) it.next();
//在一级缓存中清理
session.evict(users);
//在二级缓存中清理,二级缓存可以设定
SessionFactory.evict(TUser.class, users.getUserid());
System.out.println("user Name:"+users.getName());
}</span></strong>
但是这样的话,由于JVM的异步内存回收机制,无效对象会不断的在内存中积累等待回收,如果数据量很大,必然会频繁的激发JVM的内存回收机制,导致系统性能急剧下降。因此对于这样的问题,最好使用SQL或者存储过程!
Hibernate之list和iterator的更多相关文章
- hibernate中Query的list和iterator区别
1.Test_query_list类 public class Test_query_iterator_list { public static void main(String[] args) { ...
- 【Hibernate 7】浅谈Hibernate的缓存机制
一.Hibernate缓存机制简介 对于Hibernate本身来说,它的缓存主要包括三部分:session缓存(一级缓存).二级缓存.查询缓存. 1.1,session缓存 随着session的关闭而 ...
- HIbernate学习笔记(八) hibernate缓存机制
hibernate缓存 一. Session级缓存(一级缓存) 一级缓存很短和session的生命周期一致,因此也叫session级缓存或事务级缓存 hibernate一级缓存 那些方法支持一级缓存: ...
- Hibernate 学习教程
第1课 课程内容. 6 第2课Hibernate UML图. 6 第3课 风格. 7 第4课 资源. 7 第5课 环境准备. 7 第6课 第一个演示样例HibernateHelloWorld 7 第7 ...
- Hibernate 马士兵 学习笔记 (转)
目录(?)[+] 第2课 Hibernate UML图 第3课 风格 第4课 资源 第5课 环境准备 第6课 第一个示例Hibernate HelloWorld 第7课 建立Annotation版本的 ...
- Hibernate学习大全
第1课 课程内容. 6 第2课Hibernate UML图. 6 第3课 风格. 7 第4课 资源. 7 第5课 环境准备. 7 第6课 第一个示例HibernateHelloWorld 7 第7课 ...
- Hibernate 二级缓存疑难点
一级缓存:缓存实体 二级缓存:缓存实体 Hibernate查询缓存缓存的是查询出来的实体的部分属性结果集和实体的ID(注意这里不是实体). Hibernate查询缓存:对List起作用.但是Hiber ...
- 【Hibernate步步为营】--hql查询小介
HQL 是指Hibernate Query Language,它是Hibernate的查询语言,拥有一套自己的查询机制,它的查询语句和SQL非常类似.在使用的时候可以非常快上手.HQL提供了基本上SQ ...
- hibernate的list和iterate的区别
一.先介绍一下java中的缓存系统JCS(java cache system) 1.JCS(Java Caching System)是一个对象Cache,它可以把Java对象缓存起来,提高那些访问频 ...
- Hibernate之HQL基本用法
关于HQL HQL与SQL非常类似,只不过SQL的操作对象是数据表,列等对象,而HQL操作的是持久化类,实例,属性等. HQL是完全面向对象的查询语言,因此也具有面向对象的继承,多态等特性. 使用HQ ...
随机推荐
- 零基础入门Vue之影分身之术——列表渲染&渲染原理浅析
听我说 从 条件渲染 那一篇,我学习到了如何用Vue对dom节点根据条件显示 但单单有条件还不够啊,有时候数据是一大坨一大坨的数据,如果Vue不提供咱要么使用"v-html" 要么 ...
- Python-集合的基本操作(set)
1. 前言 python中的集合和数学里的类似也是用于存放不重复的元素,它有可变集合(set)和不可变集合(feozenset)两种,集合的所有元素都放在一对大括号"{}"里(列表 ...
- NC14419 线路规划
题目链接 题目 题目描述 Q国的监察院是一个神秘的组织. 这个组织掌握了整个帝国的地下力量,监察着Q国的每一个人. 监察院一共有N个成员,每一个成员都有且仅有1个直接上司,而他只听从其上直接司的命令. ...
- NC19246 数据结构
题目链接 题目 题目描述 qn姐姐最好了~ qn姐姐给你了一个长度为n的序列还有m次操作让你玩, 1 l r 询问区间[l,r]内的元素和 2 l r 询问区间[l,r]内的元素的平方和 3 l r ...
- Linux 中iostat 命令详解
iostat命令详解 iostat 主要是统计 磁盘活动情况. iostat有以下缺陷: iostat的输出结果大多数是一段时间内的平均值,因此难以反映峰值情况iostat仅能对系统整体情况进行分析汇 ...
- SpringCloud服务注册与发现Eureka实战
介绍 Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务 ...
- Linux中作业控制命令
开门见山,最近.NET劝退师要在linux上写些长时间运行的脚本,获取Azure BlobStorage存储的数据. 记录一下Linux中后台执行作业的命令. Linux作业 作业(Job)是shel ...
- 微信小程序生态13-微信公众号自定义菜单配置
序 微信公众号分为订阅号和服务号两种,虽然二者很大的不同,但是这两种公众号的底部却是差不多的:都有菜单栏,而且这些底部菜单也都是自定义配置的. 如CSDN的官方公众号的底部就有精彩栏目.新程序员.CS ...
- std::weak_ptr 与 std::shared_ptr 配合使用
std::shared_ptr<int> a = std::make_shared<int>(2); std::weak_ptr<int> b = a; a = n ...
- centos7.5 hadoop NAT 静态IP网络环境搭建
1 设置 VMware 网络环境 1. 选择VMNet8 并将子网IP 修改为 192.168.10.0,保证集群ip都在这个网段下 2. 选择NAT 设置,配置NAT的网关为 192.168.10. ...