1.采用List查询
执行一条sql语句,查出所需数据.
Result:
Hibernate: select student0_.id as id0_, student0_.createTime as createTime0_, student0_.name as name0_, student0_.classesid as classesid0_ from t_student student0_
班级0的学生0
班级0的学生1
班级0的学生2
班级1的学生3
班级1的学生4
班级1的学生5
Code:
@SuppressWarnings("unchecked")
public void testQuery1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
/**
* 采用list查询实体对象会发出一条查询语句,取得实体对象数据
*
*/
List students = session.createQuery("from Student").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
2.采用Iterate查询
#.首先发出一条查询ID列表的sql. 然后会发出N条sql去加载相关的对象.若缓存中不存在相关对象.就会产生1+N次SQl查询问题.
#.若缓存中存在相关对象时,就会根据Id列表去拿相关对象.并将数据存入缓存中.
Result:
Hibernate: select student0_.id as col_0_0_ from t_student student0_
Hibernate: select student0_.id as id0_0_, student0_.createTime as createTime0_0_, student0_.name as name0_0_, student0_.classesid as classesid0_0_ from t_student student0_ where student0_.id=?
班级0的学生0
Hibernate: select student0_.id as id0_0_, student0_.createTime as createTime0_0_, student0_.name as name0_0_, student0_.classesid as classesid0_0_ from t_student student0_ where student0_.id=?
班级0的学生1
Hibernate: select student0_.id as id0_0_, student0_.createTime as createTime0_0_, student0_.name as name0_0_, student0_.classesid as classesid0_0_ from t_student student0_ where student0_.id=?
班级0的学生2
Hibernate: select student0_.id as id0_0_, student0_.createTime as createTime0_0_, student0_.name as name0_0_, student0_.classesid as classesid0_0_ from t_student student0_ where student0_.id=?
班级1的学生3
Hibernate: select student0_.id as id0_0_, student0_.createTime as createTime0_0_, student0_.name as name0_0_, student0_.classesid as classesid0_0_ from t_student student0_ where student0_.id=?
班级1的学生4
Hibernate: select student0_.id as id0_0_, student0_.createTime as createTime0_0_, student0_.name as name0_0_, student0_.classesid as classesid0_0_ from t_student student0_ where student0_.id=?
班级1的学生5
Code:
@SuppressWarnings("unchecked")
public void testQuery2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
/**
* 会出现N+1问题,所谓的N+1指的是发出了N+1条sql语句
*
* 1:发出一条查询id列表的语句
*
* N:根据id发出N条sql语句,加载相关的对象
*/
Iterator iter = session.createQuery("from Student").iterate();
while (iter.hasNext()) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
总结:
#1. list()方法会一次取出所有的结果集对象,而且他会依据查询的结果初始化所有的结果集对象。如果在结果集非常庞大的时候会占据非常多的内存,甚至会造成内存溢出的情况发生.
iterate()方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象。一次在访问中可以控制缓存中对象的数量,以避免占用过多的缓存,导致内存溢出情况的发生.
#2. 返回类型不一样.
list()方法返回list.且list中每个对象都是原来的对象.
iterate()方法返回iterator,返回的是代理对象.
#3. list()会直接查数据库; iterate()会先把数据库中所有id取出来,等真正需要某个对象时再根据id先去查缓存.若没有,再去执行一条sql去查数据库,这样子就会产生所说的1+n次的问题.