`
asdewq287
  • 浏览: 17127 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate查询实体对象

阅读更多
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);
        }
    }
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics