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()更適用於查詢對象開啓二級緩存的狀況! */