hibernate的抓取策略和懒加载

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

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

    以学生和班级为例:

    抓取策略:
   1、研究的主要是set集合如何提取数据
   2、在Classes.hbm.xml文件中
       <set fetch="join/select/subselect">
            join        左外连接
               如果把需求分析翻译sql语句,存在子查询,这个时候用该策略不起作用
            select      默认
               先查询一的一端,再查询多的一端
            subselect   子查询
               如果需要分析翻译成sql语句存在子查询,这个时候用该策略效率最高

例子示例:

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

对应的class映射文件配置

<set name="students" cascade="save-update" inverse="true" fetch="join">
			<!-- 
				key是用来描述外键
			 -->
			<key>
				<column name="cid"></column>
			</key>
			<one-to-many class="cn.itcast.hiberate.sh.domain.Student"/>
		</set>

对应的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<Student> 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、单端关联的懒加载(多对一)
        <many-to-one lazy="false/no-proxy/proxy">  no-porxy 默认值  true
        根据多的一端加载一的一端,就一个数据,所以无所谓


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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值