Hibernate学习29 -- Hibernate查询语言(HQL)3 -- 实体对象查询

本文探讨了Hibernate中list和iterate方法的区别,特别是在处理N+1查询问题时的行为差异。通过示例代码展示了如何避免不必要的数据库查询,提高应用程序性能。

实体对象查询:

²        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问题。

例子1代码如下:

/**

 * 实体对象查询

 */

public class SimpleObjectQueryTest1 extends TestCase {

 

    public void testQuery1() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();       

           //返回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());

           }

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

    }  

    public void testQuery2() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();       

           //返回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());

           }

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

    }  

    public void testQuery3() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();

          

           //返回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());

           }

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

    }  

    public void testQuery4() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();       

           //返回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());

           }

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

    }         

    public void testQuery5() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();       

           //不支持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());

           }

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

    }  

}

例子2代码如下:

/**

 * 实体对象查询

 */

public class SimpleObjectQueryTest2 extends TestCase {

    public void testQuery1() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();       

           /**

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

           }

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

    }  

    public void testQuery2() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();       

           /**

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

           }

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

    }     

    public void testQuery3() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();       

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

           }         

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

    }

    public void testQuery4() {

       Session session = null;

       try {

           session = HibernateUtils.getSession();

           session.beginTransaction();       

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

           }

           session.getTransaction().commit();

       }catch(Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       }finally {

           HibernateUtils.closeSession(session);

       }

    }  

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值