示例演示查询list与iterate的区别
1、实体对象的查询,查询的是实体对象的数据【重要】
* 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);
}
}
}
详细查看注释部分代码.
以后对查询的性能优化..