理解Hibernate延迟加载策略

延迟加载(lazy load):应用只有在需要时才去数据库中抓取相应的记录。通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销

如果对一个类或者集合配置了延迟检索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于Session范围内)时,才能初始化它。如果在游离状态时才初始化它,就会产生延迟初始化错误。所以,在开发独立的DAO数据访问层时应该格外小心这个问题。

  如果在获取对象的时候使用的是session.get()是不会延迟加载的,只有在使用load、hql时候才会延迟加载。

       Hibernate中允许使用延迟加载的地方主要有以下几个地方

<hibernate-mapping default-lazy=(true|false)>:设置全局的延迟加载策略。默认true

<class lazy=(true|false)>:默认值为true.只对普通属性起作用,对集合和<one-to-one> <many-to-one>不起作用

<property lazy=(true|false)>:设置字段延迟加载,默认为false.如果类设置了延迟加载,属性再设置无效。如果只对部分property进行延迟加载的话, hibernate还提供了另外的方式,也是更为推荐的方式,即HQL或者条件查询。

<many-to-one lazy=(proxy|no-proxy|false)>:默认为proxy

<one-to-one lazy=(proxy|no-proxy|false)>:默认为proxy

<set lazy=(true|extra|false)>:默认为true

<list lazy=(true|extra|false)>:默认为true


<map lazy=(true|extra|false)>:默认为true

<bag lazy=(true|extra|false)>:默认为true

<ibag lazy=(true|extra|false)>:默认为true

<component lazy=(true|false):默认为false

<subclass lazy=(true|false)>:默认设置为true

<join-subclass lazy=(true|false)>:默认设置为true

<union-subclass lazy=(true|false)>:默认设置为true

User.xml

<hibernate-mapping>
<class name="wb.wk.review.mapping.onetomany.doubleMapping.Users" table="tbl_user" lazy="true">
<id name="id" column="id" type="java.lang.Integer">
<generator class="identity"></generator>
</id>
<property name="userName" type="java.lang.String" column="user_name"/>
<property name="password" type="java.lang.String" column="password"/>
<!-- 一对多双向关联 
对于 <set.../> 元素来说,lazy="true"是默认值)
-->
<set name="bank" table="tbl_bank" cascade="all" inverse="true" lazy="extra">
<key column="user_id" /><!-- 确定关联的外键列 -->
            <one-to-many class="wb.wk.review.mapping.onetomany.doubleMapping.Bank"/>
</set>
</class>
</hibernate-mapping>

Bank.xml

<hibernate-mapping>
<class name="wb.wk.review.mapping.onetomany.doubleMapping.Bank" table="tbl_bank">
<id name="id" column="id" type="java.lang.Integer">
<generator class="identity"></generator>
</id>
<property name="bankCard" type="java.lang.String" column="bank_card"/>
<!-- 一对多双向关联 -->
<many-to-one name="users" class="wb.wk.review.mapping.onetomany.doubleMapping.Users" 
column="user_id"  >
</many-to-one>
</class>
</hibernate-mapping>

测试Main:

Session session=null;
Transaction tran=null;

try {
session=HibernateSessionFactory.getSession();
tran=session.beginTransaction();
Users user=(Users) session.load(Users.class, 17);
System.out.println(user.getUserName());
user.getBank();
System.out.println(user.getBank().size());
} catch (HibernateException e) {
e.printStackTrace();
}finally{
session.flush();
session.close();
}

当使用extra 出现sql: select  count(id)  from tbl_bank where user_id =?

当使用 true,出现sql: select  bank0_.user_id as user3_1_, bank0_.id as id1_,
        bank0_.id as id1_0_, bank0_.bank_card as bank2_1_0_, bank0_.user_id as user3_1_0_ 
    from  tbl_bank bank0_   where  bank0_.user_id=?

extra 调用集合的size/contains等方法的时候,hibernate 并不会去加载整个集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据.比如便利集合的时候。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值