String hql = "from Student";
Query query = session.createQuery(hql);
对于这条语句的查询:
List<Student> stus = query.list();
会把所有的查询结果放到list中。一次加载到内存。
语句:select student0_.id as id3_, student0_.studentage as studentage3_, student0_.studentname as studentn3_3_ from Student student0_//当执行list方法的时候
Iterator<Student> stus = query.iterate();
该语句只把ID的值放到迭代器中,当遍历的时候,会根据ID的值再去数据库中查。并且该语句会产生N+1次查询。
语句1:select student0_.id as col_0_0_ from Student student0_ //当执行iterate方法的时候
语句2:select student0_.id as id3_0_, student0_.studentage as studentage3_0_, student0_.studentname as studentn3_3_0_ from Student student0_ where student0_.id=?//遍历获取值的时候
这两个方法各有千秋。请根据具体情况选择使用(牺牲内存或者牺牲网络资源)。
二、list和iterator
1 、list方法会直接直接到数据库中加载数据,然后将查询结果放入缓存中,当然如果你配置了查询缓存,他会先进入查询缓存寻找,如果没有满足条件的再进入数据库加载数据;
2、iterator方法在查询时是先从数据库中查询出所有满足条件的数据索引,然后再根据这些数据索引进入一级和二级缓存进行匹配,如果对于数据索引有实体对象则直接返回该对象,如果没有则在具体使用对象的时候才会进入数据库加载数据,并且把数据索引和对于实体对象放进缓存;
3、什么时候使用最合适呢?个人建议第一次查询使用list直接从数据库中读取所有数据,然后放到了缓存中,后面使用Iterator,直接从缓存中读取,利于提高性能;(你预期返回的结果在session,或二级缓存(second-level cache)中已经存在时)
三,实例演示:
实体对象的查询,查询的是实体对象的数据【重要】 *n+1问题,在默认配置的情况下,使用query.iterate()操作,有可能有n+1问题,所谓n+1,指在查询对象数据的时候,发出了n+1条查询语句。 1:首先发出了一条查询语句,查询对象的id列表 n:在迭代访问每个对象的时候,如果缓存中没有对象数据,Hibernate会在此发出一条查询语句, 查询相应的对象 *List操作与Iterate操作的区别 list,每次都会发出一条查询语句,查询所有的对象 iterate,首先发出一条查询语句,查询对象的id列表,然后根据缓存情况,决定 是否发出更多的查询语句,来查询对象数据
package com.bjsxt.hibernate; import java.util.Iterator; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import junit.framework.TestCase; /** * 对象查询中的list操作和iterator操作的差异 * @author Administrator * */ public class SimpleObjectQueryTest2 extends TestCase { public void testQueryWithListMethod() { Session session = null; try { session = HibernateUtils.getSession(); /** * 将发出一条查询语句,获取Student的集合数据 * select student0_.id as id1_, student0_.name as name1_, * student0_.createTime as createTime1_, student0_.classid as classid1_ * from t_student student0_ */ List students = session.createQuery("from Student").list(); for (Iterator iter = students.iterator();iter.hasNext();) { Student student = (Student)iter.next(); System.out.println(student.getName()); } }catch(Exception e) { e.printStackTrace(); }finally { HibernateUtils.closeSession(session); } } public void testQueryWithIterateMethod() { Session session = null; try { session = HibernateUtils.getSession(); //先发出查询id的列表语句 //select student0_.id as col_0_0_ from t_student student0_ //再依次发出查询对象的sql(根据id) //select student0_.id as id1_0_, student0_.name as name1_0_, //student0_.createTime as createTime1_0_, student0_.classid as classid1_0_ //from t_student student0_ where student0_.id=? Query query = session.createQuery("from Student"); Iterator students = query.iterate(); while (students.hasNext()) { Student student = (Student)students.next(); System.out.println(student.getName()); } }catch(Exception e) { e.printStackTrace(); }finally { HibernateUtils.closeSession(session); } } public void testQueryWithListAndIterate() { Session session = null; try { session = HibernateUtils.getSession(); Query query = session.createQuery("from Student"); List students = query.list(); for (Iterator iter = students.iterator();iter.hasNext();) { Student student = (Student)iter.next(); System.out.println(student.getName()); } //如果使用iterate进行查询 //因为list操作已经将对象加载到了session的一级缓存,所以 //再使用iterate操作的时候,它先会发出查询id列表的查询语句 //再根据id到缓存中获取相关的数据 //只有再缓存中找不到相关数据的情况下,才会再次发出sql进行查询 Iterator studentsIter = query.iterate(); while (studentsIter.hasNext()) { Student student = (Student)studentsIter.next(); System.out.println(student.getName()); } }catch(Exception e) { e.printStackTrace(); }finally { HibernateUtils.closeSession(session); } } public void testQueryWithListAndList() { Session session = null; try { session = HibernateUtils.getSession(); Query query = session.createQuery("from Student"); List students = query.list(); for (Iterator iter = students.iterator();iter.hasNext();) { Student student = (Student)iter.next(); System.out.println(student.getName()); } //再次发出sql //在默认情况下,list每次都会向数据库发出查询对象数据的sql, //除非配置了查询缓存,所以下面的list()操作,虽然在session已经有了 //对象缓存数据,但list()并不理会这个中缓存,而再次发出查询语句进行查询 students = query.list(); for (Iterator iter = students.iterator();iter.hasNext();) { Student student = (Student)iter.next(); System.out.println(student.getName()); } }catch(Exception e) { e.printStackTrace(); }finally { HibernateUtils.closeSession(session); } } }
相关推荐
今天我们将探讨的是Hibernate的二级缓存,特别是`list`和`iterate`方法的区别,这对于优化数据库访问性能至关重要。 一级缓存是Hibernate内置的,它是Session级别的缓存,自动管理实体对象的生命周期。然而,一级...
提供的源码`s2sh_relation23_list_iterate`可能包含了演示如何使用Hibernate进行查询和遍历结果的实例。通过阅读和运行这些代码,你可以深入理解`list()`和`iterator()`在实际项目中的应用。 总之,理解和掌握`...
以下是对标题和描述中提到的HibernateTemplate方法的详细总结: A. `get` 和 `load`: 这两个方法都是用于从数据库中获取单个对象。`get`方法直接返回一个实体对象,如果数据库中没有找到对应ID的数据,则返回null...
关于iterate和list的使用,由于无法确保查询条件的重复性,通常很难保证iterate能充分利用缓存。而且,iterate可能会导致1+N问题,因为即使有缓存,每次迭代时仍需检查数据库是否存在新数据。相比之下,list在某些...
本文将详细介绍如何利用Struts和Hibernate来实现对Oracle数据库中所有记录的查询及显示功能。 #### 二、技术背景介绍 1. **Struts**:Struts是一个开源的MVC(Model-View-Controller)框架,主要用于简化Web应用...
//该方法将到classpath下解析hibernate.cfg.xml中的配置,如果不用Hibernate默认的配置文件名和路径,可在该方法中指定Hibernate配置文件的名称和路径 2.用Configuration对象获取SessionFactory和Session对象:...
Query 对象提供了许多方法来查询持久化对象,例如 list、iterate 等。Query 对象可以根据不同的条件来查询持久化对象。 Hibernate 的核心接口分别是 Configuration、SessionFactory、Session、Transaction 和 Query...
### Hibernate语句大全 #### 一、概述 Hibernate是一个开源的对象关系映射(ORM)框架,它能够将Java对象映射到数据库表中,并管理这些对象的生命周期。本篇文章主要介绍初学者在学习Hibernate时会遇到的基础语句...
- `list()`、`uniqueResult()`、`iterate()`等方法处理查询结果。 3. **更新(Update)** - 修改对象的属性,然后调用`Session`的`update()`方法将对象的状态同步到数据库。 - 或者,先`load()`或`get()`对象,...
### HIBERNATE_QUERY知识点详解 #### 一、概述 Hibernate作为一款强大的对象关系映射...以上就是关于Hibernate查询机制的相关知识点介绍,通过这些方法和技术,开发者可以根据具体的应用需求选择最合适的查询方式。
17.1.10 按主键逐个处理查询结果(iterate()方法) 17.1.11 可滚动的结果集 17.1.12 在HQL查询语句中绑定参数 17.1.13 设置查询附属事项 17.1.14 在映射文件中定义命名查询语句 17.1.15 在HQL查询语句中...
`单端代理的批量抓取.PNG` 可能讲解了如何通过Hibernate的批处理技术提高性能,如设置批处理大小,利用Session的flush模式,以及Query的iterate()和list()方法的区别。批量操作可以减少数据库交互次数,提升应用性能...
总的来说,合理利用Hibernate的二级缓存可以极大地提升系统性能,但同时也需要注意缓存管理和一致性问题,避免出现数据不一致和内存资源浪费。在实际开发中,应根据具体的应用场景和数据特性来设计和优化缓存策略。
**Hibernate4 学习笔记** Hibernate4 是一个流行的开源对象关系映射(ORM)框架,它简化了Java...在实际开发中,合理配置和使用二级缓存、选择合适的查询方法以及理解load和get的区别,都能显著提升数据库操作的效率。
3. **检索**: `Session`的`get()`、`load()`方法获取单个实体,`list()`, `scroll()`, `iterate()`用于查询结果集。 4. **删除**: 使用`Session`的`delete()`方法删除实体。 5. **事务处理**: 在事务边界内执行...
List()和iterate查询的主要区别在于,List每次都会查询SQL并放入缓存,而iterate在缓存中不存在数据时可能出现N+1问题。 `get()`和`load()`方法都会利用一级缓存,当对象被加载到Session时,数据首先会被存入缓存而...