深入理解Hibernate中Iterate方法
一、数据准备(参考前面一篇博文)
数据准备参考博文(这是链接) 
在实际需求中有时需要对一些业务数据进行频繁的查询处理,可能会这样处理: 
二、list查询剖析
public void testQuerySingleTable_HQL_List() {
        Session session = HbnUtils.getSession();
        try {
            session.beginTransaction();
            String hql = "from Student where age > 17";
            // 执行第一次查操作
            List<Student> list = session.createQuery(hql).list();
            for (Student stu : list) {
            System.out.println(stu);
            }
            System.out.println("\t-------第一次查询与第二次查询的分割线--------");
            // 执行第二次查操作
            List<Student> list_1 = session.createQuery(hql).list();
            for (Student stu : list) {
                System.out.println(stu);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }下面是控制台打印的SQL语句和提示语句
Hibernate: 
    select
        student0_.t_id as t_id1_0_,
        student0_.t_name as t_name2_0_,
        student0_.t_age as t_age3_0_,
        student0_.t_score as t_score4_0_ 
    from
        t_student student0_ 
    where
        student0_.t_age>17
Student [id=8, name=张8三, age=18, score=88.0]
Student [id=9, name=张9三, age=19, score=89.0]
Student [id=10, name=张10三, age=20, score=90.0]
    -------第一次查询与第二次查询的分割线--------
Hibernate: 
    select
        student0_.t_id as t_id1_0_,
        student0_.t_name as t_name2_0_,
        student0_.t_age as t_age3_0_,
        student0_.t_score as t_score4_0_ 
    from
        t_student student0_ 
    where
        student0_.t_age>17
Student [id=8, name=张8三, age=18, score=88.0]
Student [id=9, name=张9三, age=19, score=89.0]
Student [id=10, name=张10三, age=20, score=90.0]从上面的输出信息可以看出,用List方法Hibernate查询了几次就访问了几次数据库,为了提高效率,本应该在第二次查询的时候可以从缓存中获取,因为第一次的结果已经保存在Session缓存中了!
三、iterate查询剖析
代码
/**
* iterate
 *  */
    @Test
    public void testQuerySingleTable_HQL_Iterate() {
        Session session = HbnUtils.getSession();
        try {
            session.beginTransaction();
            String hql = "from Student where age>17";
            // 执行(第一次查询)
            Iterator<Student> iterator = session.createQuery(hql).iterate();
            while(iterator.hasNext()){
                System.out.println(iterator.next());
            }
            System.out.println("\t-------第一次查询与第二次查询的分割线--------");
            //执行第二次查询操作
            List<Student> list_1 = (List<Student>) session.createQuery(hql).iterate();
            while(iterator.hasNext()){
                System.out.println(iterator.next());
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }执行后控制台输出信息
Hibernate: 
    select
        student0_.t_id as col_0_0_ 
    from
        t_student student0_ 
    where
        student0_.t_age>17
Hibernate: 
    select
        student0_.t_id as t_id1_0_0_,
        student0_.t_name as t_name2_0_0_,
        student0_.t_age as t_age3_0_0_,
        student0_.t_score as t_score4_0_0_ 
    from
        t_student student0_ 
    where
        student0_.t_id=?
Student [id=8, name=张8三, age=18, score=88.0]
Hibernate: 
    select
        student0_.t_id as t_id1_0_0_,
        student0_.t_name as t_name2_0_0_,
        student0_.t_age as t_age3_0_0_,
        student0_.t_score as t_score4_0_0_ 
    from
        t_student student0_ 
    where
        student0_.t_id=?
Student [id=9, name=张9三, age=19, score=89.0]
Hibernate: 
    select
        student0_.t_id as t_id1_0_0_,
        student0_.t_name as t_name2_0_0_,
        student0_.t_age as t_age3_0_0_,
        student0_.t_score as t_score4_0_0_ 
    from
        t_student student0_ 
    where
        student0_.t_id=?
Student [id=10, name=张10三, age=20, score=90.0]
    -------第一次查询与第二次查询的分割线--------
Hibernate: 
    select
        student0_.t_id as col_0_0_ 
    from
        t_student student0_ 
    where
        student0_.t_age>17分析输出信息可以看出:Hibernate的iterate执行过程 
 1): 
Hibernate:  
 select 
 student0_.t_id as col_0_0_ 
 from 
 t_student student0_ 
 where 
 student0_.t_age>17 
 Student [id=8, name=张8三, age=18, score=88.0] 
 Student [id=9, name=张9三, age=19, score=89.0] 
 Student [id=10, name=张10三, age=20, score=90.0]
 1):先把所有满足条件的记录的id从数据库查询出来 
 2):然后根据查询出来的id逐个去查询每一条记录的详细信息 
 3):先根据id在Session缓存中查找 
 4):如果没有,就需要去数据库查找,有几个满足条件的id,就需要访问几次数据库 
 3):当进行第二次查询时,先到数据库进行了一次主键查询,查查满足条件的id,然后直接根据id从Session缓存中读出满足条件的记录的详细信息
四、Query接口的List方法与Iterate方法比较
List方法不会从Session缓存中读取数据
Iterate方法会从Session缓存中读取数据
List方法第一次查询效率高
Iterate方法第一次查询效率很低(2n+1次)
所以为了避免n+1问题,我们取长补短,第一次查询用List,第二次查询用Iterate
五、Query接口的List方法与Iterate方法结合
public void testQuerySingleTable_HQL_IterateAndList() {
        Session session = HbnUtils.getSession();
        try {
            session.beginTransaction();
            String hql = "from Student where age>17";
            // 执行(第一次查询)
            List<Student> list = session.createQuery(hql).list();
            for (Student stu : list) {
            System.out.println(stu);
            }
            System.out.println("\t-------第一次查询与第二次查询的分割线--------");
            //执行第二次查询操作
            Iterator<Student> iterator_1 = session.createQuery(hql).iterate();
            while(iterator_1.hasNext()){
                System.out.println(iterator_1.next());
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }看结果:———
Hibernate: 
    select
        student0_.t_id as t_id1_0_,
        student0_.t_name as t_name2_0_,
        student0_.t_age as t_age3_0_,
        student0_.t_score as t_score4_0_ 
    from
        t_student student0_ 
    where
        student0_.t_age>17
Student [id=8, name=张8三, age=18, score=88.0]
Student [id=9, name=张9三, age=19, score=89.0]
Student [id=10, name=张10三, age=20, score=90.0]
    -------第一次查询与第二次查询的分割线--------
Hibernate: 
    select
        student0_.t_id as col_0_0_ 
    from
        t_student student0_ 
    where
        student0_.t_age>17
Student [id=8, name=张8三, age=18, score=88.0]
Student [id=9, name=张9三, age=19, score=89.0]
Student [id=10, name=张10三, age=20, score=90.0]从结果分析效率确实提高了不少!!!
                
                










