实体对象查询

Posted on 2009-08-24 17:55  哥德巴赫猜  阅读(184)  评论(0)    收藏  举报

实体对象查询【重要】

       * N + 1问题,在默认情况下,使用query.iterate查询,有可以能出现N+1问题

         所谓的N+1是在查询的时候发出了N+1sql语句

         1: 首先发出一条查询对象id列表的sql

         N: 根据id列表到缓存中查询,如果缓存中不存在与之匹配的数据,那么会根据id发出相应的sql语句

       * listiterate的区别?

              * list每次都会发出sql语句,list会向缓存中放入数据,而不利用缓存中的数据

              * iterate:在默认情况下iterate利用缓存数据,但如果缓存中不存在数据有可以能出现N+1问题

       参见:SimpleObjectQueryTest1.java/SimpleObjectQueryTest2.java

/**

 * 实体对象查询

 * @author Administrator

 *

 */

 

           //返回Student对象的集合

           //可以忽略select

           List students = session.createQuery("from Student").list();

           for (Iterator iter=students.iterator(); iter.hasNext();) {

              Student student = (Student)iter.next();

              System.out.println(student.getName());

           }

 

 

 

    //返回Student对象的集合

           //可以忽略select,表可以使用别名

           List students = session.createQuery("from Student s").list();

           for (Iterator iter=students.iterator(); iter.hasNext();) {

              Student student = (Student)iter.next();

               System.out.println(student.getName());

           }

 

//返回Student对象的集合

           //可以忽略select,表可以使用as命名别名

           List students = session.createQuery("from Student as s").list();

           for (Iterator iter=students.iterator(); iter.hasNext();) {

              Student student = (Student)iter.next();

              System.out.println(student.getName());

           }

 

 

           //返回Student对象的集合

           //使用select查询实体对象,必须采用别名

           List students = session.createQuery("select s from Student as s").list();

           for (Iterator iter=students.iterator(); iter.hasNext();) {

              Student student = (Student)iter.next();

              System.out.println(student.getName());

           }

 

   

           //不支持select * from .....这样的查询语句

           List students = session.createQuery("select * from Student").list();

           for (Iterator iter=students.iterator(); iter.hasNext();) {

               Student student = (Student)iter.next();

              System.out.println(student.getName());

           }

**

 * 实体对象查询

 * @author Administrator

 *

 */

/**

            * 采用list查询发出一条查询语句,取得Student对象数据、

            *

            * Hibernate: select student0_.id as id1_, student0_.name as name1_,

            * student0_.createTime as createTime1_, student0_.classesid as classesid1_

            * 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());

           }

 

/**

            * 出现N+1问题

            *

            * 1:发出查询id列表的sql

            *   Hibernate: select student0_.id as col_0_0_ from t_student student0_

            *

            * N:在依次发出根据id查询Student对象的sql

            * Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_,

            * student0_.createTime as createTime1_0_, student0_.classesid as classesid1_0_

            * from t_student student0_ where student0_.id=?

            * 

            */

           Iterator iter = session.createQuery("from Student").iterate();

           while(iter.hasNext()) {

              Student student = (Student)iter.next();

              System.out.println(student.getName());

           }

 

 

List students = session.createQuery("from Student").list();

           for (Iterator iter=students.iterator(); iter.hasNext();) {

              Student student = (Student)iter.next();

              System.out.println(student.getName());

           }

           System.out.println("---------------------------------------------");

          

 

           /**

            * 不会出现N+1问题

            *

            * 因为list操作已经将Student对象放到了一级缓存中,所以再次使用iterate操作的时候

            * 它首先发出一条查询id列表的sql,在根据id到缓存中去数据,只有在缓存中找不到相应的

            * 数据时,才会发出sql到数据库中查询

            *

            */

           Iterator iter = session.createQuery("from Student").iterate();

           while(iter.hasNext()) {

              Student student = (Student)iter.next();

              System.out.println(student.getName());

           }

 

 

    List students = session.createQuery("from Student").list();

           for (Iterator iter=students.iterator(); iter.hasNext();) {

              Student student = (Student)iter.next();

              System.out.println(student.getName());

           }

           System.out.println("---------------------------------------------");

          

           /**

            * 再次发出查询sql

            *

            * 在默认情况下list每次都会向数据库发出查询对象的sql,除非配置查询缓存,所以下面的list操作

            * 虽然在一级缓存中已经有了对象数据,但list默认情况下不会利用缓存,而再次发出sql

            *

            * 默认情况下,list会向缓存中放入数据,但不会利用数据

            *

            */

           students = session.createQuery("from Student").list();

           for (Iterator iter=students.iterator(); iter.hasNext();) {

              Student student = (Student)iter.next();

              System.out.println(student.getName());

           }


博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3