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