您的位置:首页 > 其它

Hibernate懒加载、关联级别加载策略

2017-09-13 12:55 357 查看

Hibernate懒加载

对于hibernate.cfg.xml配置、Customer对象配置这里就不贴代码了,在上篇笔记里面有

Customer.hbm.xml配置如下 lazy=”true”是默认配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.domain" >
<class name="Customer" table="cst_customer" lazy="true" >
<id name="cust_id"  >
<generator class="native"></generator>
</id>
<property name="cust_name" column="cust_name" ></property>
<property name="cust_source" column="cust_source" ></property>
<property name="cust_industry" column="cust_industry" ></property>
<property name="cust_level" column="cust_level" ></property>
<property name="cust_linkman" column="cust_linkman" ></property>
<property name="cust_phone" column="cust_phone" ></property>
<property name="cust_mobile" column="cust_mobile" ></property>

<!--
lazy属性: 决定是否延迟加载
true(默认值): 延迟加载,懒加载
false: 立即加载
extra: 极其懒惰
fetch属性: 决定加载策略.使用什么类型的sql语句加载集合数据
select(默认值): 单表查询加载
join: 使用多表查询加载集合
subselect:使用子查询加载集合
-->
<!-- batch-size: 抓取集合的数量为3.
抓取客户的集合时,一次抓取几个客户的联系人集合.
-->
<set name="linkMens" batch-size="3"  >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>

</class>
</hibernate-mapping>


来看下测试代码

@Test
// get方法 : 立即加载.执行方法时立即发送sql语句查询结果
public void fun1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------

Customer c = session.get(Customer.class, 2l);
System.out.println("======fun1========");
System.out.println(c);
//----------------------------------------------------
tx.commit();
session.close();

}


在fun1测试中是即时进行加载的,输入的log如下:

Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_source as cust_sou3_0_0_,
customer0_.cust_industry as cust_ind4_0_0_,
customer0_.cust_level as cust_lev5_0_0_,
customer0_.cust_linkman as cust_lin6_0_0_,
customer0_.cust_phone as cust_pho7_0_0_,
customer0_.cust_mobile as cust_mob8_0_0_
from
cst_customer customer0_
where
customer0_.cust_id=?
======fun1========
Customer [cust_id=2, cust_name=wyf]


通过log日志就可以看出session.get(Customer.class, 2l);就输出sql语句

我们接下来看load懒加载

@Test
// load方法(默认):是在执行时,不发送任何sql语句.返回一个对象.使用该对象时,才执行查询.
// 延迟加载: 仅仅获得没有使用.不会查询.在使用时才进行查询.
// 是否对类进行延迟加载: 可以通过在class元素上配置lazy属性来控制.
//lazy:true  加载时,不查询.使用时才查询b
//lazy:false 加载时立即查询.
public void fun2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------

Customer c = session.load(Customer.class, 2l);
System.out.println("=======fun2=======");
//----------------------------------------------------
tx.commit();
System.out.println(c);
session.close();

}


通过懒加载我们看下log输出

=======fun2=======
Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_source as cust_sou3_0_0_,
customer0_.cust_industry as cust_ind4_0_0_,
customer0_.cust_level as cust_lev5_0_0_,
customer0_.cust_linkman as cust_lin6_0_0_,
customer0_.cust_phone as cust_pho7_0_0_,
customer0_.cust_mobile as cust_mob8_0_0_
from
cst_customer customer0_
where
customer0_.cust_id=?
Customer [cust_id=2, cust_name=wyf]


通过输出就可以看出来,仅仅获得没有使用.不会查询.在使用时才进行查询.

关联级别策略-客户表

fetch:select、lazy:true

<!--
lazy属性: 决定是否延迟加载
true(默认值): 延迟加载,懒加载
false: 立即加载
extra: 极其懒惰
fetch属性: 决定加载策略.使用什么类型的sql语句加载集合数据
select(默认值): 单表查询加载
join: 使用多表查询加载集合
subselect:使用子查询加载集合
-->


我们将Customer.hbm.xml修改下配置文件

<set name="linkMens" lazy="true" fetch="select"  >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>


LinkMan.hbm.xml配置默认策略

<many-to-one name="customer" column="lkm_cust_id" class="Customer"  >
</many-to-one>


来进行测试下

//集合级别的关联
//fetch:select 单表查询
//lazy:true 使用时才加载集合数据.
@Test
public void fun1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------

Customer c = session.get(Customer.class, 2l);
System.out.println("------111--------");
Set<LinkMan> linkMens = c.getLinkMens();//关联级别
System.out.println("-------222-------");
System.out.println(linkMens);

//----------------------------------------------------
tx.commit();
session.close();

}


输出log如下

Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_source as cust_sou3_0_0_,
customer0_.cust_industry as cust_ind4_0_0_,
customer0_.cust_level as cust_lev5_0_0_,
customer0_.cust_linkman as cust_lin6_0_0_,
customer0_.cust_phone as cust_pho7_0_0_,
customer0_.cust_mobile as cust_mob8_0_0_
from
cst_customer customer0_
where
customer0_.cust_id=?
------111--------
-------222-------
Hibernate:
select
linkmens0_.lkm_cust_id as lkm_cus10_1_0_,
linkmens0_.lkm_id as lkm_id1_1_0_,
linkmens0_.lkm_id as lkm_id1_1_1_,
linkmens0_.lkm_gender as lkm_gend2_1_1_,
linkmens0_.lkm_name as lkm_name3_1_1_,
linkmens0_.lkm_phone as lkm_phon4_1_1_,
linkmens0_.lkm_email as lkm_emai5_1_1_,
linkmens0_.lkm_qq as lkm_qq6_1_1_,
linkmens0_.lkm_mobile as lkm_mobi7_1_1_,
linkmens0_.lkm_memo as lkm_memo8_1_1_,
linkmens0_.lkm_position as lkm_posi9_1_1_,
linkmens0_.lkm_cust_id as lkm_cus10_1_1_
from
cst_linkman linkmens0_
where
linkmens0_.lkm_cust_id=?
[cn.itcast.domain.LinkMan@29876704, cn.itcast.domain.LinkMan@455351c4]


通过fetch:select、lazy:true对客户表进行配置执行,说明Set linkMens = c.getLinkMens();//关联级别查询不会输出sql语句,只有在使用时才加载集合数据.

fetch:select、lazy:false

我们继续看另外一种加载策略

将客户的配置修改如下

<set name="linkMens" lazy="false" fetch="select"  >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>


//集合级别的关联
//fetch:select 单表查询
//lazy:false 立即记载集合数据
@Test
public void fun2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------

Customer c = session.get(Customer.class, 2l);
System.out.println("------111--------");
Set<LinkMan> linkMens = c.getLinkMens();//关联级别
System.out.println("------222--------");
System.out.println(linkMens);

//----------------------------------------------------
tx.commit();
session.close();

}


log日志如下:

Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_source as cust_sou3_0_0_,
customer0_.cust_industry as cust_ind4_0_0_,
customer0_.cust_level as cust_lev5_0_0_,
customer0_.cust_linkman as cust_lin6_0_0_,
customer0_.cust_phone as cust_pho7_0_0_,
customer0_.cust_mobile as cust_mob8_0_0_
from
cst_customer customer0_
where
customer0_.cust_id=?
Hibernate:
select
linkmens0_.lkm_cust_id as lkm_cus10_1_0_,
linkmens0_.lkm_id as lkm_id1_1_0_,
linkmens0_.lkm_id as lkm_id1_1_1_,
linkmens0_.lkm_gender as lkm_gend2_1_1_,
linkmens0_.lkm_name as lkm_name3_1_1_,
linkmens0_.lkm_phone as lkm_phon4_1_1_,
linkmens0_.lkm_email as lkm_emai5_1_1_,
linkmens0_.lkm_qq as lkm_qq6_1_1_,
linkmens0_.lkm_mobile as lkm_mobi7_1_1_,
linkmens0_.lkm_memo as lkm_memo8_1_1_,
linkmens0_.lkm_position as lkm_posi9_1_1_,
linkmens0_.lkm_cust_id as lkm_cus10_1_1_
from
cst_linkman linkmens0_
where
linkmens0_.lkm_cust_id=?
------111--------
------222--------
[cn.itcast.domain.LinkMan@4816c290, cn.itcast.domain.LinkMan@4940809c]


fetch:select、lazy:false说明是2条单表语句,立刻查询

fetch:join、lazy:true

<set name="linkMens" lazy="true" fetch="join"  >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>


//fetch:join    多表查询
//lazy:true|false|extra 失效.立即加载.
@Test
public void fun4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------

Customer c = session.get(Customer.class, 2l);
System.out.println("------111--------");
Set<LinkMan> linkMens = c.getLinkMens();//关联级别
System.out.println("------222--------");
System.out.println(linkMens.size());

System.out.println(linkMens);

//----------------------------------------------------
tx.commit();
session.close();

}


日志输出如下:

Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_source as cust_sou3_0_0_,
customer0_.cust_industry as cust_ind4_0_0_,
customer0_.cust_level as cust_lev5_0_0_,
customer0_.cust_linkman as cust_lin6_0_0_,
customer0_.cust_phone as cust_pho7_0_0_,
customer0_.cust_mobile as cust_mob8_0_0_,
linkmens1_.lkm_cust_id as lkm_cus10_1_1_,
linkmens1_.lkm_id as lkm_id1_1_1_,
linkmens1_.lkm_id as lkm_id1_1_2_,
linkmens1_.lkm_gender as lkm_gend2_1_2_,
linkmens1_.lkm_name as lkm_name3_1_2_,
linkmens1_.lkm_phone as lkm_phon4_1_2_,
linkmens1_.lkm_email as lkm_emai5_1_2_,
linkmens1_.lkm_qq as lkm_qq6_1_2_,
linkmens1_.lkm_mobile as lkm_mobi7_1_2_,
linkmens1_.lkm_memo as lkm_memo8_1_2_,
linkmens1_.lkm_position as lkm_posi9_1_2_,
linkmens1_.lkm_cust_id as lkm_cus10_1_2_
from
cst_customer customer0_
left outer join
cst_linkman linkmens1_
on customer0_.cust_id=linkmens1_.lkm_cust_id
where
customer0_.cust_id=?
------111--------
------222--------
2
[cn.itcast.domain.LinkMan@54107f42, cn.itcast.domain.LinkMan@64712be]


lazy:true属性失效,因为是使用的多表查询,直接就查询出来了

关联级别策略-联系人表

fetch:select、lazy:proxy、customer-true 懒加载

<!--
lazy属性: 决定是否延迟加载
true(默认值): 延迟加载,懒加载
false: 立即加载
extra: 极其懒惰
fetch属性: 决定加载策略.使用什么类型的sql语句加载集合数据
select(默认值): 单表查询加载
join: 使用多表查询加载集合
subselect:使用子查询加载集合
-->
<!-- batch-size: 抓取集合的数量为3.
抓取客户的集合时,一次抓取几个客户的联系人集合.
-->
<set name="linkMens" lazy="true">
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>


<!--
fetch 决定加载的sql语句
select: 使用单表查询
join : 多表查询
lazy  决定加载时机
false: 立即加载
proxy: 由customer的类级别加载策略决定.
-->
<many-to-one name="customer" column="lkm_cust_id" class="Customer"  fetch="select" lazy="proxy" >
</many-to-one>


来看下测试代码

@Test
//fetch:select  单表查询
//lazy:proxy
//customer-true 懒加载
public void fun1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------

LinkMan lm = session.get(LinkMan.class, 3l);
System.out.println("-------111-------");
Customer customer = lm.getCustomer();
System.out.println("-------222-------");
System.out.println(customer);

//----------------------------------------------------
tx.commit();
session.close();

}


sql日志如下:

Hibernate:
select
linkman0_.lkm_id as lkm_id1_1_0_,
linkman0_.lkm_gender as lkm_gend2_1_0_,
linkman0_.lkm_name as lkm_name3_1_0_,
linkman0_.lkm_phone as lkm_phon4_1_0_,
linkman0_.lkm_email as lkm_emai5_1_0_,
linkman0_.lkm_qq as lkm_qq6_1_0_,
linkman0_.lkm_mobile as lkm_mobi7_1_0_,
linkman0_.lkm_memo as lkm_memo8_1_0_,
linkman0_.lkm_position as lkm_posi9_1_0_,
linkman0_.lkm_cust_id as lkm_cus10_1_0_
from
cst_linkman linkman0_
where
linkman0_.lkm_id=?
-------111-------
-------222-------
Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_source as cust_sou3_0_0_,
customer0_.cust_industry as cust_ind4_0_0_,
customer0_.cust_level as cust_lev5_0_0_,
customer0_.cust_linkman as cust_lin6_0_0_,
customer0_.cust_phone as cust_pho7_0_0_,
customer0_.cust_mobile as cust_mob8_0_0_
from
cst_customer customer0_
where
customer0_.cust_id=?
Customer [cust_id=1, cust_name=创智]


fetch:select、lazy:proxy、customer-false懒加载

<set name="linkMens" lazy="false">
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>


<many-to-one name="customer" column="lkm_cust_id" class="Customer"  fetch="select" lazy="proxy" >
</many-to-one>


@Test
//fetch:select  单表查询
//lazy:proxy
//customer-false 立即加载
public void fun2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------

LinkMan lm = session.get(LinkMan.class, 3l);

System.out.println("-------111-------");
Customer customer = lm.getCustomer();
System.out.println("-------222-------");

System.out.println(customer);

//----------------------------------------------------
tx.commit();
session.close();

}


sql日志如下:

Hibernate:
select
linkman0_.lkm_id as lkm_id1_1_0_,
linkman0_.lkm_gender as lkm_gend2_1_0_,
linkman0_.lkm_name as lkm_name3_1_0_,
linkman0_.lkm_phone as lkm_phon4_1_0_,
linkman0_.lkm_email as lkm_emai5_1_0_,
linkman0_.lkm_qq as lkm_qq6_1_0_,
linkman0_.lkm_mobile as lkm_mobi7_1_0_,
linkman0_.lkm_memo as lkm_memo8_1_0_,
linkman0_.lkm_position as lkm_posi9_1_0_,
linkman0_.lkm_cust_id as lkm_cus10_1_0_
from
cst_linkman linkman0_
where
linkman0_.lkm_id=?
-------111-------
-------222-------
Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_source as cust_sou3_0_0_,
customer0_.cust_industry as cust_ind4_0_0_,
customer0_.cust_level as cust_lev5_0_0_,
customer0_.cust_linkman as cust_lin6_0_0_,
customer0_.cust_phone as cust_pho7_0_0_,
customer0_.cust_mobile as cust_mob8_0_0_
from
cst_customer customer0_
where
customer0_.cust_id=?
Hibernate:
select
linkmens0_.lkm_cust_id as lkm_cus10_1_0_,
linkmens0_.lkm_id as lkm_id1_1_0_,
linkmens0_.lkm_id as lkm_id1_1_1_,
linkmens0_.lkm_gender as lkm_gend2_1_1_,
linkmens0_.lkm_name as lkm_name3_1_1_,
linkmens0_.lkm_phone as lkm_phon4_1_1_,
linkmens0_.lkm_email as lkm_emai5_1_1_,
linkmens0_.lkm_qq as lkm_qq6_1_1_,
linkmens0_.lkm_mobile as lkm_mobi7_1_1_,
linkmens0_.lkm_memo as lkm_memo8_1_1_,
linkmens0_.lkm_position as lkm_posi9_1_1_,
linkmens0_.lkm_cust_id as lkm_cus10_1_1_
from
cst_linkman linkmens0_
where
linkmens0_.lkm_cust_id=?


fetch:join、lazy:proxy、customer-true 懒加载

<set name="linkMens" lazy="true">
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>


<!--
fetch 决定加载的sql语句
select: 使用单表查询
join : 多表查询
lazy  决定加载时机
false: 立即加载
proxy: 由customer的类级别加载策略决定.
-->
<many-to-one name="customer" column="lkm_cust_id" class="Customer"  fetch="join" lazy="proxy" >
</many-to-one>


来看下测试代码:

@Test
//fetch:join    多表
//lazy: 失效
public void fun3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------

LinkMan lm = session.get(LinkMan.class, 3l);
System.out.println("-------111-------");
Customer customer = lm.getCustomer();
System.out.println("-------222-------");
System.out.println(customer);

//----------------------------------------------------
tx.commit();
session.close();

}


sql日志输出如下:

Hibernate:
select
linkman0_.lkm_id as lkm_id1_1_0_,
linkman0_.lkm_gender as lkm_gend2_1_0_,
linkman0_.lkm_name as lkm_name3_1_0_,
linkman0_.lkm_phone as lkm_phon4_1_0_,
linkman0_.lkm_email as lkm_emai5_1_0_,
linkman0_.lkm_qq as lkm_qq6_1_0_,
linkman0_.lkm_mobile as lkm_mobi7_1_0_,
linkman0_.lkm_memo as lkm_memo8_1_0_,
linkman0_.lkm_position as lkm_posi9_1_0_,
linkman0_.lkm_cust_id as lkm_cus10_1_0_,
customer1_.cust_id as cust_id1_0_1_,
customer1_.cust_name as cust_nam2_0_1_,
customer1_.cust_source as cust_sou3_0_1_,
customer1_.cust_industry as cust_ind4_0_1_,
customer1_.cust_level as cust_lev5_0_1_,
customer1_.cust_linkman as cust_lin6_0_1_,
customer1_.cust_phone as cust_pho7_0_1_,
customer1_.cust_mobile as cust_mob8_0_1_
from
cst_linkman linkman0_
left outer join
cst_customer customer1_
on linkman0_.lkm_cust_id=customer1_.cust_id
where
linkman0_.lkm_id=?
-------111-------
-------222-------
Customer [cust_id=1, cust_name=创智]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐