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)       從上面的執行結果能夠看出獲取的方式不同java

List的獲取方式爲:List<Customers> list = query.list();sql

Iterator的獲取方式:Iterator<Customers> it = query.iterate();數據庫

(2)從執行結果能夠看出list輸出一條語句,而iterator輸出的是兩條sql語句,咱們可想一下,爲何會輸出這樣的效果?緩存

由於他們獲取數據的方式不同,list()會直接查詢數據庫,iterator()會先到數據庫中把id都取出來,而後真正要遍歷某個對象的時候先到緩存中找,若是找不到,以id爲條件再發一條sql到數據庫,這樣若是緩存中沒有數據,則查詢數據庫的次數爲n+1次session

(3)list只查詢一級緩存,而iterator會從二級緩存中查性能

(4)list方法返回的對象都是實體對象,而iterator返回的是代理對象測試

(5) session中list第二次發出,仍會到數據庫査詢spa

(6) iterate 第二次,首先找session 級緩存hibernate

相關文章
相關標籤/搜索