Hibernate懶載入、關聯級別載入策略
阿新 • • 發佈:2019-01-25
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=創智]