首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

二十三 iterate查询与N+1次查询的有关问题

2012-11-13 
二十三 iterate查询与N+1次查询的问题test.javaview plaincopy to clipboardprint?01.import hibernate.Hi

二十三 iterate查询与N+1次查询的问题

test.javaview plaincopy to clipboardprint?01.import hibernate.HibernateUtil;   02.  03.import java.util.Date;   04.import java.util.Iterator;   05.  06.import org.hibernate.Query;   07.import org.hibernate.Session;   08.  09.import domain.Users;   10.  11.  12.  13.public class test {   14.  15.  16.       17.    public static void main(String[] args) {   18.        Users user = new Users();   19.        user.setBirthday(new Date());   20.        user.setName("pf1");   21.        HibernateUtil.add(user);   22.        user.setName("pf2");   23.        HibernateUtil.add(user);   24.        user.setName("pf3");   25.        HibernateUtil.add(user);   26.           27.        iterator();   28.           29.           30.    }   31.       32.    static void iterator(){   33.        Session s = HibernateUtil.getSession();   34.        Query query = s.createQuery("from Users");   35.        Iterator<Users> it = query.iterate();   36.        while(it.hasNext()){   37.            System.out.println(it.next().getName());   38.        }   39.    }   40.}  import hibernate.HibernateUtil;import java.util.Date;import java.util.Iterator;import org.hibernate.Query;import org.hibernate.Session;import domain.Users;public class test {public static void main(String[] args) {Users user = new Users();user.setBirthday(new Date());user.setName("pf1");HibernateUtil.add(user);user.setName("pf2");HibernateUtil.add(user);user.setName("pf3");HibernateUtil.add(user);iterator();}static void iterator(){Session s = HibernateUtil.getSession();Query query = s.createQuery("from Users");Iterator<Users> it = query.iterate();while(it.hasNext()){System.out.println(it.next().getName());}}} 执行结果:Hibernate: insert into Users (ver, name, birthday) values (?, ?, ?)Hibernate: insert into Users (ver, name, birthday) values (?, ?, ?)Hibernate: insert into Users (ver, name, birthday) values (?, ?, ?)Hibernate: select users0_.id as col_0_0_ from Users users0_Hibernate: select users0_.id as id0_0_, users0_.ver as ver0_0_, users0_.name as name0_0_, users0_.birthday as birthday0_0_ from Users users0_ where users0_.id=?pf1Hibernate: select users0_.id as id0_0_, users0_.ver as ver0_0_, users0_.name as name0_0_, users0_.birthday as birthday0_0_ from Users users0_ where users0_.id=?pf2Hibernate: select users0_.id as id0_0_, users0_.ver as ver0_0_, users0_.name as name0_0_, users0_.birthday as birthday0_0_ from Users users0_ where users0_.id=?pf3可以发现红色那条语句,iterator查询是先查出记录的id号,在需要的时候再去查询,查询时候先从缓存里查找,再从数据库中读取。由于我的Users是native方式生成主键,所以不会保存在缓存里,因为没访问数据库前不知道数据库生成的id号。所有的select语句加起来是4条,包括查id的语句,所以一共是N+1次查询。所以缓存没命中的情况下查询效率极低。同样懒加载的时候也会有N+1次查询的情况,第一次查询出所有当前对象,N次查询查询关联对象。懒加载也会有N+1次查询当有个部门它下面有十个员工 我们去查这个部门,当要查询这个部门下的员工时,就会出现11条select语句,一条是这个部门的查询 另外十条是根据部门id查员工的select语句如果我查询员工,通过员工去查部门,就不会有N+1次查询,因为这在查员工的时候就把部门信息给查出来了 这种情况在一对一的关系中特别明显总结 N+1次查询和懒加载     1.用Query.iterator可能会有N+1次查询。     2.懒加载时获取关联对象。     3.如果打开对查询的缓存即使用list也可能有N+1次查询。完毕 end!

?

热点排行