在Hibernate3中将Session.find(),Session.iterator()换成:session.createQuery().list(),session.createQuery().iterator(),(实现机制并没有什么区别);

两者都是根据指定条件查询并返回符合查询的条件的实体对象;

看下session.createQuery().list():

  1. List<TUser> users = session.createQuery(hql).list();   
  2. int len = users.size();   
  3. for (int i = 0; i < len; i++) {   
  4.     TUser user = users.get(i);   
  5.     System.out.println("User name:"+user.getName());   
  6. }  
<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>

在控制台上只会输出:

  1. 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>

显示的结果为:

  1. User name:keith 299  
<strong><span style="font-size:18px;color:#000000;">User name:keith 299</span></strong>

 

在看下session.createQuery().iterate():

  1. Iterator it = session.createQuery(hql).iterate();   
  2. while (it.hasNext()) {   
  3.     TUser users = (TUser) it.next();   
  4.     System.out.println("user Name:"+users.getName());   
  5. }  
<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>

 看下控制台上的输出:

  1. Hibernate: select   tuser0_.userid as col_0_0_  from  t_user tuser0_ where   tuser0_.age>316
      
  2. 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>

 所显示的结果为:

  1. 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缓存机制密切相关,我们将两种方法写在一起:

  1. List<TUser> users = session.createQuery(hql).list();   
  2. int len = users.size();   
  3. for (int i = 0; i < len; i++) {   
  4.     TUser user = users.get(i);   
  5.     System.out.println("user Name:"+user.getName());   
  6. }   
  7.   
  8. System.out.println("\n query by list is Over,and query by iterator is start...");   
  9.   
  10. Iterator it = session.createQuery(hql).iterate();   
  11.   
  12. while (it.hasNext()) {   
  13.     TUser user = (TUser) it.next();   
  14.     System.out.println("users name:"+user.getName());   
  15. }  
<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>

 看下控制台的输出:

  1. 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
      
  2.   
  3. user Name:keith 299   
  4.   
  5.  query by list is Over,and query by iterator is start...
      
  6.   
  7. Hibernate: select  tuser0_.userid as col_0_0_  from  t_user tuser0_ where  tuser0_.age>316
      
  8.   
  9. 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()来解决吧!将内存消耗保持在可以接受的范围内;比如:

  1. Iterator it = session.createQuery(hql).iterate();   
  2. while (it.hasNext()) {   
  3.     TUser users = (TUser) it.next();   
  4.     //在一级缓存中清理
      
  5.     session.evict(users);   
  6.     //在二级缓存中清理,二级缓存可以设定
      
  7.     SessionFactory.evict(TUser.class, users.getUserid());   
  8.     System.out.println("user Name:"+users.getName());   
  9. }  
<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的更多相关文章

  1. hibernate中Query的list和iterator区别

    1.Test_query_list类 public class Test_query_iterator_list { public static void main(String[] args) { ...

  2. 【Hibernate 7】浅谈Hibernate的缓存机制

    一.Hibernate缓存机制简介 对于Hibernate本身来说,它的缓存主要包括三部分:session缓存(一级缓存).二级缓存.查询缓存. 1.1,session缓存 随着session的关闭而 ...

  3. HIbernate学习笔记(八) hibernate缓存机制

    hibernate缓存 一. Session级缓存(一级缓存) 一级缓存很短和session的生命周期一致,因此也叫session级缓存或事务级缓存 hibernate一级缓存 那些方法支持一级缓存: ...

  4. Hibernate 学习教程

    第1课 课程内容. 6 第2课Hibernate UML图. 6 第3课 风格. 7 第4课 资源. 7 第5课 环境准备. 7 第6课 第一个演示样例HibernateHelloWorld 7 第7 ...

  5. Hibernate 马士兵 学习笔记 (转)

    目录(?)[+] 第2课 Hibernate UML图 第3课 风格 第4课 资源 第5课 环境准备 第6课 第一个示例Hibernate HelloWorld 第7课 建立Annotation版本的 ...

  6. Hibernate学习大全

    第1课 课程内容. 6 第2课Hibernate UML图. 6 第3课 风格. 7 第4课 资源. 7 第5课 环境准备. 7 第6课 第一个示例HibernateHelloWorld 7 第7课 ...

  7. Hibernate 二级缓存疑难点

    一级缓存:缓存实体 二级缓存:缓存实体 Hibernate查询缓存缓存的是查询出来的实体的部分属性结果集和实体的ID(注意这里不是实体). Hibernate查询缓存:对List起作用.但是Hiber ...

  8. 【Hibernate步步为营】--hql查询小介

    HQL 是指Hibernate Query Language,它是Hibernate的查询语言,拥有一套自己的查询机制,它的查询语句和SQL非常类似.在使用的时候可以非常快上手.HQL提供了基本上SQ ...

  9. hibernate的list和iterate的区别

    一.先介绍一下java中的缓存系统JCS(java cache system)  1.JCS(Java Caching System)是一个对象Cache,它可以把Java对象缓存起来,提高那些访问频 ...

  10. Hibernate之HQL基本用法

    关于HQL HQL与SQL非常类似,只不过SQL的操作对象是数据表,列等对象,而HQL操作的是持久化类,实例,属性等. HQL是完全面向对象的查询语言,因此也具有面向对象的继承,多态等特性. 使用HQ ...

随机推荐

  1. Vulkan学习苦旅04:创建设备(逻辑设备VkDevice)

    设备是对物理设备的一种抽象,使我们更加方便地使用它.更准确地说,应该称其为"逻辑设备",但由于逻辑设备在Vulkan中极为常用,后面几乎所有的API都需要它作为第一个参数,因此在V ...

  2. 基本数据类型(primitive type)

    数据类型 数据类型分为基本数据类型(primitive type)和引用数据类型(reference type) 基本数据类型(primitive type) 数值类型 整数类型 浮点类型 字符类型 ...

  3. (python)做题记录||2024.2.4||题目是codewars的【 All Balanced Parentheses】

    题目链接:https://www.codewars.com/kata/5426d7a2c2c7784365000783/python 我的解决方案: def balanced_parens(n): # ...

  4. 《ASP.ENT Core 与 RESTful API 开发实战》-- (第5章)-- 读书笔记(上)

    第 5 章 使用 Entity Framework Core 5.1 Entity Framework Core EF Core 是微软推出的 ORM 框架,一种为了解决高级编程语言中的对象和关系型数 ...

  5. centos7创建MySQL自动备份脚本

    说明 最近需要给wordpress站点搞一个定时备份mysql数据库,所以记录一下. 操作步骤 1.创建备份脚本 这一步最重要,创建目录:/home/wpblog_backup,然后在目录下创建she ...

  6. BUG管理系统(Mantis)迁移实战

    Mantis迁移实战 名词解释 Mantis:  开源的BUG管理平台Mantis,也做MantisBT.           同档次产品有EasyBUG,QC,BugFree,Bugzila. Xa ...

  7. React18 之 Suspense

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 本文作者:佳岚 Suspense Suspense 组件我们并不陌生 ...

  8. docker启动nginx https自签名证书配置

    启动测试应用时, 有时需要自己配置证书签名: 1 使用系统自带openssl openssl req \ > -x509 \ > -nodes \ > -days 365 \ > ...

  9. 以二进制文件安装K8S之部署Master高可用集群

    如下以二进制文件方式部署安全的Kubernetes Master高可用集群,具体步骤如下: 1.下载Kubernetes服务的二进制文件 2.部署kube-apiserver服务 3.创建客户端CA证 ...

  10. 商店销售预测(回归&随机森林)

    ​ 目录 一.题目概要 二.导入包和数据集 三.数据处理 四.描述性分析 五.探索性数据分析 六.模型一:线性回归 七.模型2:随机森林 一.题目概要 在Kaggle竞赛中,要求我们应用时间序列预测, ...