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); } } }
相关推荐
NULL 博文链接:https://364232252.iteye.com/blog/2369137
3 list和iterate不同之处(//主要为了面试 详见hibernate_2900_Hibernate_list_iterate) 4 一级缓存和二级缓存和査询缓存(面试题)(详见hibernate_3000_Hibernate_3KindsOf_Cache) 5 事务并发处理(面试的意义...
//该方法将到classpath下解析hibernate.cfg.xml中的配置,如果不用Hibernate默认的配置文件名和路径,可在该方法中指定Hibernate配置文件的名称和路径 2.用Configuration对象获取SessionFactory和Session对象:...
17.1.10 按主键逐个处理查询结果(iterate()方法) 17.1.11 可滚动的结果集 17.1.12 在HQL查询语句中绑定参数 17.1.13 设置查询附属事项 17.1.14 在映射文件中定义命名查询语句 17.1.15 在HQL查询语句中...
当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load(),以及调用查询接口的list()、iterate()或filter()方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级...
17.1.10 按主键逐个处理查询结果(iterate()方法) 17.1.11 可滚动的结果集 17.1.12 在HQL查询语句中绑定参数 17.1.13 设置查询附属事项 17.1.14 在映射文件中定义命名查询语句 17.1.15 在HQL查询语句中...
17.1.10 按主键逐个处理查询结果(iterate()方法) 17.1.11 可滚动的结果集 17.1.12 在HQL查询语句中绑定参数 17.1.13 设置查询附属事项 17.1.14 在映射文件中定义命名查询语句 17.1.15 在HQL查询语句中...
17.1.10 按主键逐个处理查询结果(iterate()方法) 17.1.11 可滚动的结果集 17.1.12 在HQL查询语句中绑定参数 17.1.13 设置查询附属事项 17.1.14 在映射文件中定义命名查询语句 17.1.15 在HQL查询语句中...
CONTENT表字段上,在Spring中采用OracleLobHandler来处理Lob字段(包括Clob和Blob),由于在程序中不需要引用到oracle数据驱动程序的具体类且屏蔽了不同数据库处理Lob字段方法上的差别,从而撤除程序在多数据库移植...
读取hibernate的配置文件和映射文件 3.构建SessionFactory对象 Transaction 1.事务管理对象 Query 1.查询对象,HQL Criteria 1.hibernate提供的更面向对象的一种查询方式。 准备工作: 1.java中的POJO对象存在...