hibernate05–list和iterator详解编程语言

package cn.bdqn.test; 
 
import java.util.Iterator; 
import java.util.List; 
 
import org.hibernate.Query; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.Transaction; 
import org.hibernate.cfg.Configuration; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 
 
import cn.bdqn.bean.Student; 
import cn.bdqn.util.HibernateSessionUtil; 
 
 
public class StudentTest { 
     
    Session session=null; 
    Transaction transaction=null; 
     
    @Before 
    public  void  before(){ 
        //getCurrentSession  必须在事务下运行 
        session=HibernateSessionUtil.getCurrentSession(); 
        transaction=session.beginTransaction(); //开启事务 
    } 
     
    /** 
     * HQL: hibernate查询语言! 
     *  
     *  执行hql的步骤: 
     *  01.获取session对象 
     *  02.编写hql语句  使用面向对象的思想!  hql中只有类 和属性  !不存在 表和字段 
     *  03.通过session.createQuery(String hql) 创建Query对象 
     *  05.执行对应的查询 
     */ 
     
     
    /** 
     * list查询所有: 
     *  01.会立即产生一条select语句! 
     *    select查询出来的所有数据,都会被session管理!保存在缓存中! 
     *  02.清空或者不清空session缓存中的数据 
     *  03.再次执行查询的时候 都会执行一条select语句! 
     */ 
    @Test 
    public  void  testList(){ 
        //Student 必须大写  因为是 类名 
        String hql="from Student"; 
        //创建Query对象 
        Query query = session.createQuery(hql); 
        //执行对应的查询 
        System.out.println("*************"); 
        List<Student> list = query.list(); 
        System.out.println("*************"); 
        for (Student student : list) { 
            System.out.println(student); 
        } 
        //清空缓存 
        //session.clear(); 
        //再次执行对应的查询 
        list = query.list(); 
        for (Student student : list) { 
            System.out.println(student); 
        } 
    } 
     
    /** 
     * Iterator:查询所有 
     *  
     * 测试环境:数据库中有5条数据 
     *  
     * 产生的结果: 
     *    01.6条select语句 
     *    02.第一条 是查询数据库表中所有的id,这条语句是query.iterate()产生的! 
     *    03.其他的5条select语句 都是根据id进行查询!都是在.next()产生的! 
     */ 
    @Test 
    public  void  testIterator(){ 
        String hql="from Student"; 
        Query query = session.createQuery(hql); 
        System.out.println("*************"); 
        Iterator<Student> iterate = query.iterate(); 
        System.out.println("*************"); 
        while (iterate.hasNext()) { 
            System.out.println("*************"); 
            Student stu = iterate.next(); 
            System.out.println("*************"); 
            System.out.println(stu); 
        } 
    } 
     
     
    /** 
     * 01.iterate在有缓存的情况下,如果缓存中有查询的所有数据!只会执行一条sql语句! 
     * 这条sql就是查询所有的id! 
     * 02.如果缓存中有2条数据! id =1  id=2 
     *    我们查询了所有的5条数据! 
     *    这时候会产生多少条sql?  3+1 
     */ 
    @Test 
    public  void  testIterator2(){ 
        String hql="from Student"; 
        Query query = session.createQuery(hql); 
        Iterator<Student> iterate = query.iterate(); 
        while (iterate.hasNext()) { 
            Student stu = iterate.next(); 
            System.out.println(stu); 
        } 
        System.out.println("********************"); 
        //再次查询  没有清空缓存 
        iterate = query.iterate(); 
        while (iterate.hasNext()) { 
            Student stu = iterate.next(); 
            System.out.println(stu); 
        } 
    } 
     
    /** 
     * 测试环境: 
     *    缓存中有两条数据 
     * 结果: 
     *   01.get肯定产生sql 
     *   02.iterate遍历的时候 先去缓存中获取已经存在的数据! 就会减少2次查询! 
     */ 
     @Test 
        public  void  testIterator21(){ 
           //获取id为1的student对象 
        Student student1= (Student) session.get(Student.class, 1); // 产生1条 
        Student student2 = (Student) session.get(Student.class, 2); // 产生1条 
        System.out.println("*************************"); 
        String hql="from Student"; 
        Query query = session.createQuery(hql); 
        Iterator<Student> iterate = query.iterate(); // 产生1条 
        while (iterate.hasNext()) { 
            Student stu = iterate.next();// 产生4条 
            System.out.println(stu); 
        } 
         
        } 
   
/** 
    *iterate在没有缓存的情况下 会执行N+1条数据! 
     *N:指的是数据数量!  
     *1:查询所有的ID! 
     */ 
    @Test 
    public  void  testIterator3(){ 
        String hql="from Student"; 
        Query query = session.createQuery(hql); 
        Iterator<Student> iterate = query.iterate(); 
        while (iterate.hasNext()) { 
            Student stu = iterate.next(); 
            System.out.println(stu); 
        } 
        System.out.println("********************"); 
        //再次查询 清空缓存 
        session.clear(); 
        iterate = query.iterate(); 
        while (iterate.hasNext()) { 
            Student stu = iterate.next(); 
            System.out.println(stu); 
        } 
    }
}
复制代码

 

/** 
 
    Query接口中的list()和iterate()都可以执行查询操作,
而iterate()能够利用延迟加载和缓存的机制提高查询性能!iterate()查询时,
仅查询ID字段以节省资源。需要使用数据时,再根据ID字段到缓存中检索匹配的实例!
如果存在就直接使用!只有当缓存中没有需要的数据时,iterate()才会执行select语句
!根据ID字段到数据库中查询!iterate()更适用于查询对象开启二级缓存的情况! */

list 和 iterato r的区别:

(1)       从上面的执行结果可以看出获取的方式不一样

List的获取方式为:List<Customers> list = query.list();

Iterator的获取方式:Iterator<Customers> it = query.iterate();

(2)从执行结果可以看出list输出一条语句,而iterator输出的是两条sql语句,我们可想一下,为什么会输出这样的效果?

因为他们获取数据的方式不一样,list()会直接查询数据库,iterator()会先到数据库中把id都取出来,然后真正要遍历某个对象的时候先到缓存中找,如果找不到,以id为条件再发一条sql到数据库,这样如果缓存中没有数据,则查询数据库的次数为n+1次

(3)list只查询一级缓存,而iterator会从二级缓存中查

(4)list方法返回的对象都是实体对象,而iterator返回的是代理对象

(5) session中list第二次发出,仍会到数据库査询

(6) iterate 第二次,首先找session 级缓存

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/12115.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论