HQL (二) 实体对象查询

实体对象查询(重要)  
   * N+1问题,在默认情况下使用query.iterate查询,有可能出现N+1问题,所谓的N+1
     是查询对象的时候发出了N+1条sql语句
    1:首先发出一条查询id列表的sql
    N:根据id列表发出n条查询语句

* list和iterate的区别?
   * list在默认情况下,只向缓存中放入数据,而不利用缓存中的数据
   * iterate在默认情况下有N+1问题,如果缓存中存在数据那么会根据id到缓存获取数据
     也就说iterate是利用缓存的
参见:SimpleObjectQueryTest1.java,SimpleObjectQueryTest2.java    

Java代码 复制代码 收藏代码
  1. package com.wlh.hibernate;   
  2.   
  3. import java.util.Iterator;   
  4. import java.util.List;   
  5.   
  6. import junit.framework.TestCase;   
  7.   
  8. import org.hibernate.Query;   
  9. import org.hibernate.Session;   
  10.   
  11. public class SimpleObjectQueryTest1 extends TestCase{   
  12.      
  13.     public void testQuery1(){   
  14.       Session  session=null;   
  15.       try {   
  16.             session = HibernateUtils.getSession();   
  17.             session.beginTransaction();   
  18.             //返回值为实体对象的集合   
  19.             //可以省略select语句   
  20.             Query query=session.createQuery("from Student");   
  21.             List students=query.list();   
  22.             for(Iterator iter=students.iterator();iter.hasNext();){   
  23.                 Student student=(Student)iter.next();   
  24.                 System.out.println("student="+student.getName());   
  25.             }   
  26.             session.getTransaction().commit();   
  27.         }catch(Exception e) {   
  28.             e.printStackTrace();   
  29.             session.getTransaction().rollback();   
  30.         }finally {   
  31.             HibernateUtils.closeSession(session);   
  32.         }   
  33.   }   
  34.     public void testQuery2(){   
  35.           Session  session=null;   
  36.           try {   
  37.                 session = HibernateUtils.getSession();   
  38.                 session.beginTransaction();   
  39.                 //返回值为实体对象的集合   
  40.                 //可以省略select语句,实体类可以加别名   
  41.                 Query query=session.createQuery("from Student s");   
  42.                 List students=query.list();   
  43.                 for(Iterator iter=students.iterator();iter.hasNext();){   
  44.                     Student student=(Student)iter.next();   
  45.                     System.out.println("student="+student.getName());   
  46.                 }   
  47.                 session.getTransaction().commit();   
  48.             }catch(Exception e) {   
  49.                 e.printStackTrace();   
  50.                 session.getTransaction().rollback();   
  51.             }finally {   
  52.                 HibernateUtils.closeSession(session);   
  53.             }   
  54.       }   
  55.        
  56.     public void testQuery3(){   
  57.           Session  session=null;   
  58.           try {   
  59.                 session = HibernateUtils.getSession();   
  60.                 session.beginTransaction();   
  61.                  //返回值为实体对象的集合   
  62.                 //可以省略select语句,实体类可以用as加别名   
  63.                 Query query=session.createQuery("from Student as s");   
  64.                 List students=query.list();   
  65.                 for(Iterator iter=students.iterator();iter.hasNext();){   
  66.                     Student student=(Student)iter.next();   
  67.                     System.out.println("student="+student.getName());   
  68.                 }   
  69.                 session.getTransaction().commit();   
  70.             }catch(Exception e) {   
  71.                 e.printStackTrace();   
  72.                 session.getTransaction().rollback();   
  73.             }finally {   
  74.                 HibernateUtils.closeSession(session);   
  75.             }   
  76.       }   
  77.        
  78.     public void testQuery4(){   
  79.           Session  session=null;   
  80.           try {   
  81.                 session = HibernateUtils.getSession();   
  82.                 session.beginTransaction();   
  83.                 //返回值为实体对象的集合   
  84.                 //使用select查询实体对象,必须采用别名   
  85.                 Query query=session.createQuery("select s from Student as s");   
  86.                 List students=query.list();   
  87.                 for(Iterator iter=students.iterator();iter.hasNext();){   
  88.                     Student student=(Student)iter.next();   
  89.                     System.out.println("student="+student.getName());   
  90.                 }   
  91.                 session.getTransaction().commit();   
  92.             }catch(Exception e) {   
  93.                 e.printStackTrace();   
  94.                 session.getTransaction().rollback();   
  95.             }finally {   
  96.                 HibernateUtils.closeSession(session);   
  97.             }   
  98.       }   
  99. }   
  100.   
  101.   
  102. package com.wlh.hibernate;   
  103.   
  104. import java.util.Iterator;   
  105. import java.util.List;   
  106.   
  107. import junit.framework.TestCase;   
  108.   
  109. import org.hibernate.Query;   
  110. import org.hibernate.Session;   
  111.   
  112. public class SimpleObjectQueryTest2 extends TestCase{   
  113.      
  114.     /**  
  115.      * 发出list查询  
  116.      */  
  117.     public void testQuery1(){   
  118.       Session  session=null;   
  119.       try {   
  120.             session = HibernateUtils.getSession();   
  121.             session.beginTransaction();   
  122.             /**  
  123.              * 采用list查询将会发出一条查询语句,取得Student数据  
  124.              * select student0_.id as id1_, student0_.name as name1_,   
  125.              * student0_.createTime as createTime1_, student0_.classesid as classesid1_   
  126.              * from t_student student0_  
  127.              *   
  128.              */  
  129.             Query query=session.createQuery("from Student");   
  130.             List students=query.list();   
  131.             for(Iterator iter=students.iterator();iter.hasNext();){   
  132.                 Student student=(Student)iter.next();   
  133.                 System.out.println("student="+student.getName());   
  134.             }   
  135.             session.getTransaction().commit();   
  136.         }catch(Exception e) {   
  137.             e.printStackTrace();   
  138.             session.getTransaction().rollback();   
  139.         }finally {   
  140.             HibernateUtils.closeSession(session);   
  141.         }   
  142.   }   
  143.        
  144.        
  145.     /**  
  146.      * 出现N+1问题  
  147.      *   
  148.      * 发出查询id类表的sql语句:  
  149.      *  select student0_.id as col_0_0_ from t_student student0_  
  150.      *    
  151.      * 依次发出根据id查询Student的sql语句:  
  152.      * select student0_.id as id1_0_, student0_.name as name1_0_,   
  153.      * student0_.createTime as createTime1_0_, student0_.classesid as classesid1_0_   
  154.      * from t_student student0_ where student0_.id=?  
  155.      *   
  156.      */  
  157.     public void testQuery2(){   
  158.           Session  session=null;   
  159.           try {   
  160.                 session = HibernateUtils.getSession();   
  161.                 session.beginTransaction();   
  162.                    
  163.                 Query query=session.createQuery("from Student");   
  164.                 Iterator iter=query.iterate();   
  165.                 while(iter.hasNext()){   
  166.                     Student student=(Student)iter.next();   
  167.                     System.out.println("student="+student.getName());   
  168.                 }   
  169.                 session.getTransaction().commit();   
  170.             }catch(Exception e) {   
  171.                 e.printStackTrace();   
  172.                 session.getTransaction().rollback();   
  173.             }finally {   
  174.                 HibernateUtils.closeSession(session);   
  175.             }   
  176.       }   
  177.          
  178.        
  179.     /**  
  180.      * 先发出list查询,再发出iterate查询  
  181.      */  
  182.     public void testQuery3(){   
  183.         Session  session=null;   
  184.         try {   
  185.                 session = HibernateUtils.getSession();   
  186.                 session.beginTransaction();   
  187.                 Query query=null;   
  188.                    
  189.                  query=session.createQuery("from Student");   
  190.                 List students=query.list();   
  191.                 for(Iterator iter=students.iterator();iter.hasNext();){   
  192.                     Student student=(Student)iter.next();   
  193.                     System.out.println("student="+student.getName());   
  194.                 }   
  195.                 System.out.println("===============================");   
  196.                 /**  
  197.                  * 不会出新N+1问题  
  198.                  *   
  199.                  * 因为list操作已经将对象放到了一级缓存中(session级缓存),所以在使用Iterate操作的时候  
  200.                  * 它会发出根据id查询的语句,取得id列表,再根据id到缓存中获取数据,只有在缓存中找不到相应的数据  
  201.                  * 才会发出sql语句到数据库中查询  
  202.                  */  
  203.                 query=session.createQuery("from Student");   
  204.                 Iterator iter=query.iterate();   
  205.                 while(iter.hasNext()){   
  206.                     Student student=(Student)iter.next();   
  207.                     System.out.println("student="+student.getName());   
  208.                 }   
  209.                 session.getTransaction().commit();   
  210.             }catch(Exception e) {   
  211.                 e.printStackTrace();   
  212.                 session.getTransaction().rollback();   
  213.             }finally {   
  214.                 HibernateUtils.closeSession(session);   
  215.             }   
  216.   
  217. }   
  218.        
  219.     /**  
  220.      * 发出两次list查询  
  221.      */  
  222.     public void testQuery4() {   
  223.         Session session = null;   
  224.         try {   
  225.             session = HibernateUtils.getSession();   
  226.             session.beginTransaction();   
  227.                
  228.             List students = session.createQuery("from Student").list();   
  229.                
  230.             for (Iterator iter =students.iterator(); iter.hasNext();) {   
  231.                 Student student = (Student)iter.next();   
  232.                 System.out.println(student.getName());   
  233.             }   
  234.             System.out.println("------------------------------------------------");   
  235.                
  236.             /**  
  237.              * 再次发出查询语句  
  238.              *   
  239.              * 在默认情况下list每次都会向数据库发出查询对象的sql,除非配置了查询缓存,所以下面的list  
  240.              * 操作,虽然在一级缓存中已经有了对象数据,list不会利用缓存中的数据,而再次发出查询sql  
  241.              *   
  242.              * list在默认情况下,只向缓存中放入数据,而不利用缓存中的数据  
  243.              */  
  244.             students = session.createQuery("from Student").list();   
  245.                
  246.             for (Iterator iter =students.iterator(); iter.hasNext();) {   
  247.                 Student student = (Student)iter.next();   
  248.                 System.out.println(student.getName());   
  249.             }   
  250.             session.getTransaction().commit();   
  251.         }catch(Exception e) {   
  252.             e.printStackTrace();   
  253.             session.getTransaction().rollback();   
  254.         }finally {   
  255.             HibernateUtils.closeSession(session);   
  256.         }   
  257.     }              
  258.        
  259. }  
posted @ 2011-11-22 10:54  java学弟  阅读(550)  评论(0编辑  收藏  举报