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=创智]
相关文章推荐
- SSH与SSM学习之hibernate23——关联级别加载策略之集合关联加载策略
- SSH与SSM学习之hibernate24——关联级别加载策略之属性关联加载策略
- Hibernate中类级别和关联级别加载策略
- 【JavaWeb-21】多对多关系、类和关联级别的加载策略、HQL查询详解、Hibernate连接池配置、Hibernate里悲观锁乐观锁使用
- hibernate关联策略 查询优化之关联级别查询
- SSH与SSM学习之hibernate22——类级别加载策略
- [原创]java WEB学习笔记91:Hibernate学习之路-- -HQL 迫切左外连接,左外连接,迫切内连接,内连接,关联级别运行时的检索策略 比较。理论,在于理解
- hibernate 延迟加载和抓取策略
- Hibernate懒加载问题导致View层无法获取关联数据的问题
- Hibernate深入学习(四):类级别的检索策略
- Hibernate 关联映射 之 一对多单项关联 (二)聪明的懒加载
- hibernate加载策略之lazy
- Hibernate之加载策略(延迟加载与即时加载)和抓取策略(fetch)
- 浅谈hibernate急迫加载问题(多重外键关联)
- Hibernate性能调优--关联实体的延迟加载
- Hibernate检索策略之5.3.2一对一单向(主键)关联检索策略——Hibernate4究竟怎么玩
- Hibernate关联映射,级联(cascade),抓取策略(fetch)
- Hibernate懒加载策略
- Hibernate中的取策略延迟加载(翻译hibernate官方文挡19章部分内容)
- Hibernate使用LAZY延迟加载,initialize获取延迟加载关联内容