查询实体对象:
n+1问题:在默认情况下,使用query.iterator()查询,有可能有n+1问题,所谓n+1是指在查询对象的时候发出n+1条查询语句。
1:先发出查询id列表的sql语句。
N:再发出根据id到缓存中查询,如果缓存中有与之匹配的数据,就从缓存中取得数据,否则依次根据id发出sql语句。
list和iterator到区别:
list:在默认情况下,list每次都会发出sql查询实体对象,list会向缓存里放数据,但是不会利用缓存中的数据。
iterator:首先发出一条查询id列表的sql语句,如果缓存中有与之匹配的数据,就从缓存中取得数据,否则依次根据id发出sql语句。
- import java.util.Iterator;
- import java.util.List;
- import junit.framework.TestCase;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- //...
- public class QueryTest extends TestCase {
- public void testQuery1() {
- Session session = null;
- Transaction t = null;
- try {
- session = HibernateUtils.getSession();
- t = session.beginTransaction();
- /**
- * 采用list查询,将发出一条sql语句来获取student数据
- * Hibernate: select student0_.id as id1_, student0_.name as name1_ from Student student0_
- 张三
- 李四
- */
- List<Student> list = session.createQuery("from Student").list();
- for (Iterator<Student> iter = list.iterator(); iter.hasNext();) {
- Student student = iter.next();
- System.out.println(student.getName());
- }
- t.commit();
- } catch (Exception e) {
- e.printStackTrace();
- t.rollback();
- } finally {
- HibernateUtils.closeSession(session);
- }
- }
- public void testQuery2() {
- Session session = null;
- Transaction t = null;
- try {
- session = HibernateUtils.getSession();
- t = session.beginTransaction();
- /**
- * N+1问题:
- * 使用iterator,先发出查询id列表的sql语句,
- * Hibernate: select student0_.id as col_0_0_ from Student student0_
- * 再发出根据id查询实体对象的sql
- * Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_ from Student student0_ where student0_.id=?
- 张三
- Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_ from Student student0_ where student0_.id=?
- 李四
- ×
- */
- Iterator<Student> it = session.createQuery("from Student").iterate();
- while(it.hasNext()){
- Student student = it.next();
- System.out.println(student.getName());
- }
- t.commit();
- } catch (Exception e) {
- e.printStackTrace();
- t.rollback();
- } finally {
- HibernateUtils.closeSession(session);
- }
- }
- public void testQuery3() {
- Session session = null;
- Transaction t = null;
- try {
- session = HibernateUtils.getSession();
- t = session.beginTransaction();
- List<Student> list = session.createQuery("from Student").list();
- for (Iterator<Student> iter = list.iterator(); iter.hasNext();) {
- Student student = iter.next();
- System.out.println(student.getName());
- }
- System.out.println("=======================");
- /**
- * 不会出现n+1问题
- * 因为list操作已经将对象加入到一级缓存,所以在使用iterator的时候,
- * 他首先发出查询id列表的sql,再根据id到缓存中获取数据,
- * 只有在缓存中找不到,才再次发出sql语句
- Hibernate: select student0_.id as id1_, student0_.name as name1_ from Student student0_
- 张三
- 李四
- =======================
- Hibernate: select student0_.id as col_0_0_ from Student student0_
- 张三
- 李四
- */
- Iterator<Student> it = session.createQuery("from Student").iterate();
- while(it.hasNext()){
- Student student = it.next();
- System.out.println(student.getName());
- }
- t.commit();
- } catch (Exception e) {
- e.printStackTrace();
- t.rollback();
- } finally {
- HibernateUtils.closeSession(session);
- }
- }
- }
转载于:https://blog.51cto.com/huqianhao/955189