深入理解Hibernate中Iterate方法

    xiaoxiao2021-03-25  89

    深入理解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]

    从结果分析效率确实提高了不少!!!

    转载请注明原文地址: https://ju.6miu.com/read-19610.html

    最新回复(0)