hibernate的抓取策略和懒加载

2014-11-24 01:37:11 · 作者: · 浏览: 0

抓取策略应用的范围及作用:

主要用于set集合对象在提取数据时对hibernate底层的sql语句的操作,即由一个对象对关联对象查询,发出怎样的sql语句的机制。

以学生和班级为例:

抓取策略:
1、研究的主要是set集合如何提取数据
2、在Classes.hbm.xml文件中

join 左外连接
如果把需求分析翻译sql语句,存在子查询,这个时候用该策略不起作用
select 默认
先查询一的一端,再查询多的一端
subselect 子查询
如果需要分析翻译成sql语句存在子查询,这个时候用该策略效率最高

例子示例:

/**
     * 查询所有班级下的所有学生
     * 解决问题的方案:子查询  fetch="subselect"
     */
    //@Test
    public void testAll_Classes(){
        Session session = sessionFactory.openSession();
        List
  
    cList = session.createQuery("from Classes").list();
        for(Classes classes:cList){
            Set
   
     students = classes.getStudents(); for(Student student:students){ System.out.println(student.getSname()); } } session.close(); }
   
  

对应的class映射文件配置

  
			
   
			
    
     
   
			
   
		
  

对应的hibernate输出的sql语句
Hibernate: 
    select
        classes0_.cid as cid0_,
        classes0_.cname as cname0_,
        classes0_.description as descript3_0_ 
    from
        Classes classes0_
Hibernate: 
    select
        students0_.cid as cid0_1_,
        students0_.sid as sid1_,
        students0_.sid as sid1_0_,
        students0_.sname as sname1_0_,
        students0_.description as descript3_1_0_,
        students0_.cid as cid1_0_ 
    from
        Student students0_ 
    where
        students0_.cid= 

当配置文件改为

\输出sql语句为:

Hibernate: 
    select
        classes0_.cid as cid0_,
        classes0_.cname as cname0_,
        classes0_.description as descript3_0_ 
    from
        Classes classes0_
Hibernate: 
    select
        students0_.cid as cid0_1_,
        students0_.sid as sid1_,
        students0_.sid as sid1_0_,
        students0_.sname as sname1_0_,
        students0_.description as descript3_1_0_,
        students0_.cid as cid1_0_ 
    from
        Student students0_ 
    where
        students0_.cid= 

不存在子查询的列子:

@Test
	/**
	 * 查询班级号为1的所有学生
	 */
	public void testQueryClasses_Id(){
		Session session = sessionFactory.openSession();
		Classes classes = (Classes)session.get(Classes.class, 1L);
		Set
  
    students = classes.getStudents();
		for(Student student:students){
			System.out.println(student.getSname());
		}
		session.close();
	}
  
配置文件为: \输出sql语句为:

Hibernate: 
    select
        classes0_.cid as cid0_0_,
        classes0_.cname as cname0_0_,
        classes0_.description as descript3_0_0_ 
    from
        Classes classes0_ 
    where
        classes0_.cid= 
Hibernate: 
    select
        students0_.cid as cid0_1_,
        students0_.sid as sid1_,
        students0_.sid as sid1_0_,
        students0_.sname as sname1_0_,
        students0_.description as descript3_1_0_,
        students0_.cid as cid1_0_ 
    from
        Student students0_ 
    where
        students0_.cid= 


配置文件为: \sql语句为:

Hibernate: 
    select
        classes0_.cid as cid0_1_,
        classes0_.cname as cname0_1_,
        classes0_.description as descript3_0_1_,
        students1_.cid as cid0_3_,
        students1_.sid as sid3_,
        students1_.sid as sid1_0_,
        students1_.sname as sname1_0_,
        students1_.description as descript3_1_0_,
        students1_.cid as cid1_0_ 
    from
        Classes classes0_ 
    left outer join
        Student students1_ 
            on classes0_.cid=students1_.cid 
    where
        classes0_.cid= 

一般来讲,发出的sql语句越少性能越高。



关于懒加载:

当要取出的set集合中的数据量很大时,我们使用懒加载,即当我们需要用到该对象时,才从数据库里加载,即当出现使用student.getXxx()等方法时才加载session.get()方法是不加载。


懒加载
1、类的懒加载
1、利用session.load方法可以产生代理对象
2、在session.load方法执行的时候并不发出sql语句
3、在得到其一般属性的时候发出sql语句
4、只针对一般属性有效,针对标示符属性是无效的
5、默认情况就是懒加载
2、集合的懒加载
false 当session.get时,集合就被加载出来了
true 在遍历集合的时候才加载
extra
针对集合做count,min,max,sum等操作
3、单端关联的懒加载(多对一)
no-porxy 默认值 true
根据多的一端加载一的一端,就一个数据,所以无所谓


总结:懒加载主要解决了一个问题:类、集合、many-to-one在时候发出SQL语句,加载数据