所谓懒加载(lazy)就是延时加载,就是当在真正需要数据的时候,才真正执行数据加载操作

  至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,因为内存容量有限 ,为了减少并发量,减少系统资源的消耗,我们让数据在需要的时候才进行加载,这时我们就用到了懒加载。

1.类级别的懒加载(session.load()方法)

  get方法:没有任何策略.调用即立即查询数据库加载数据.

  load方法: 应用类级别的加载策略

1.get方法测试,没有任何延迟加载策略

    @Test// get方法 : 立即加载.执行方法时立即发送sql语句查询结果public void fun1(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();//----------------------------------------------------
        Customer customer = session.get(Customer.class, 1l);//执行完此句即查询发出SQL
        System.out.println(customer);//----------------------------------------------------
        tx.commit();session.close();}

 

 没有延迟加载的get方法执行时候就发出SQL请求,且生成的对象是原生的JavaBean对象。

  

2.load方法测试,测试懒加载策略

修改配置文件懒加载设为true,默认就是开启懒加载的.比如我们查询customer的时候不会查询linkman,而我们调用get方法获取linkman的时候才去获取linkman。

    lazy(默认值):true, 查询类时,会返回代理对象.会在使用属性时,根据关联的session查询数据库.加载数据.

     lazy:false. load方法会与get方法没有任何区别.调用时即加载数据.

    结论:为了提高效率.建议使用延迟加载(懒加载)

原理:

  延迟加载是生成javaassist代理对象,生成代理对象的作用是依赖于session在使用对象的时候利用session去查询数据库,所以在使用懒加载时要确保,调用属性加载数据时,session还是打开的.不然会抛出异常

测试代码:

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

查看生成的代理对象:(代理对象的名称后面带有$符号)

注意:我们在使用懒加载的时候不能再关闭session之后再使用对象,因为懒加载的代理对象依赖session再使用对象的时候查询数据库,如下面的代码是错误的:

    public void fun2(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();//----------------------------------------------------
        Customer customer = session.load(Customer.class, 1l);//----------------------------------------------------
        tx.commit();session.close();System.out.println(customer);}

结果会报错:

2.关联级别的查询(fetch、lazy、batch-size属性)

1.集合策略(根据客户关联查询联系人集合)

配置简介:

<?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.qlq.domain" ><class name="Customer" table="cst_customer" ><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"><key column="lkm_cust_id" ></key><one-to-many class="LinkMan" /></set></class>
</hibernate-mapping>

(1)fetch为select的测试:

  • lazy=true的测试
    // 集合级别的关联// fetch:select 单表查询// lazy:true 使用时才加载集合数据.
    @Testpublic void fun1() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
Customer c = session.get(Customer.class, 7l);Set<LinkMan> linkMens = c.getLinkMens();// 关联级别
System.out.println(linkMens);//打印SQL// ----------------------------------------------------
        tx.commit();session.close();}

SQL:

Hibernate: selectcustomer0_.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_ fromcst_customer customer0_ wherecustomer0_.cust_id=?
Hibernate: selectlinkmens0_.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_ fromcst_linkman linkmens0_ wherelinkmens0_.lkm_cust_id=?
[LinkMan [lkm_id=3, lkm_gender=null, lkm_name=王八, lkm_phone=null, lkm_email=null, lkm_qq=null, lkm_mobile=null, lkm_memo=null, lkm_position=null, customer=Customer [cust_id=7, cust_name=测试名称1]], LinkMan [lkm_id=4, lkm_gender=null, lkm_name=田七, lkm_phone=null, lkm_email=null, lkm_qq=null, lkm_mobile=null, lkm_memo=null, lkm_position=null, customer=Customer [cust_id=7, cust_name=测试名称1]]]

  • lazy=false的测试(会立即加载)
    // 集合级别的关联// fetch:select 单表查询// lazy:false 立即记载集合数据
    @Testpublic void fun2() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
Customer c = session.get(Customer.class, 7l);//加载所有SQL,包括查询linkman
Set<LinkMan> linkMens = c.getLinkMens();// 关联级别
System.out.println(linkMens);// ----------------------------------------------------
        tx.commit();session.close();}

  • lazy=xetra极其懒惰,与懒加载效果基本一致. 如果只获得集合的size.只查询集合的size(count语句)
    // 集合级别的关联// fetch:select 单表查询// lazy:extra 极其懒惰.与懒加载效果基本一致. 如果只获得集合的size.只查询集合的size(count语句)
    @Testpublic void fun3() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
Customer c = session.get(Customer.class, 7l);Set<LinkMan> linkMens = c.getLinkMens();// 关联级别
System.out.println(linkMens.size());//count   SQL
System.out.println(linkMens);//查询SQL// ----------------------------------------------------
        tx.commit();session.close();}

SQL:

Hibernate: selectcustomer0_.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_ fromcst_customer customer0_ wherecustomer0_.cust_id=?
Hibernate: selectcount(lkm_id) fromcst_linkman wherelkm_cust_id =?
2
Hibernate: selectlinkmens0_.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_ fromcst_linkman linkmens0_ wherelinkmens0_.lkm_cust_id=?

(2)fetch为join的多表查询: 延迟策略失效

    // 集合级别的关联// fetch:join 多表查询// lazy:true|false|extra 失效.立即加载.
    @Testpublic void fun4() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
Customer c = session.get(Customer.class, 7l);Set<LinkMan> linkMens = c.getLinkMens();// 关联级别
System.out.println(linkMens.size());System.out.println(linkMens);// ----------------------------------------------------
        tx.commit();session.close();}

SQL:

    selectcustomer0_.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_ fromcst_customer customer0_ left outer joincst_linkman linkmens1_ on customer0_.cust_id=linkmens1_.lkm_cust_id wherecustomer0_.cust_id=?

(3)fetch为subselect (只有在批量查询的时候才有用,如果是查询单个的话与select的作用一样)

  • lazy为true
    @Test// fetch: subselect 子查询// lazy: true 懒加载public void fun5() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
String hql = "from Customer";Query query = session.createQuery(hql);List<Customer> list = query.list();for (Customer c : list) {System.out.println(c);System.out.println(c.getLinkMens().size());System.out.println(c.getLinkMens());}// ----------------------------------------------------
        tx.commit();session.close();}

SQL:

Hibernate: selectcustomer0_.cust_id as cust_id1_0_,customer0_.cust_name as cust_nam2_0_,customer0_.cust_source as cust_sou3_0_,customer0_.cust_industry as cust_ind4_0_,customer0_.cust_level as cust_lev5_0_,customer0_.cust_linkman as cust_lin6_0_,customer0_.cust_phone as cust_pho7_0_,customer0_.cust_mobile as cust_mob8_0_ fromcst_customer customer0_
Customer [cust_id=7, cust_name=测试名称1]
Hibernate: selectlinkmens0_.lkm_cust_id as lkm_cus10_1_1_,linkmens0_.lkm_id as lkm_id1_1_1_,linkmens0_.lkm_id as lkm_id1_1_0_,linkmens0_.lkm_gender as lkm_gend2_1_0_,linkmens0_.lkm_name as lkm_name3_1_0_,linkmens0_.lkm_phone as lkm_phon4_1_0_,linkmens0_.lkm_email as lkm_emai5_1_0_,linkmens0_.lkm_qq as lkm_qq6_1_0_,linkmens0_.lkm_mobile as lkm_mobi7_1_0_,linkmens0_.lkm_memo as lkm_memo8_1_0_,linkmens0_.lkm_position as lkm_posi9_1_0_,linkmens0_.lkm_cust_id as lkm_cus10_1_0_ fromcst_linkman linkmens0_ wherelinkmens0_.lkm_cust_id in (selectcustomer0_.cust_id fromcst_customer customer0_)

  • lazy为false,立即加载
    @Test// fetch: subselect 子查询// lazy: false 立即加载public void fun6() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
String hql = "from Customer";Query query = session.createQuery(hql);List<Customer> list = query.list();for (Customer c : list) {System.out.println(c);System.out.println(c.getLinkMens().size());System.out.println(c.getLinkMens());}// ----------------------------------------------------tx.commit();session.close();}

  • lazy为extra
    @Test// fetch: subselect 子查询// lazy: extra 极其懒惰public void fun7() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
String hql = "from Customer";Query query = session.createQuery(hql);List<Customer> list = query.list();for (Customer c : list) {System.out.println(c);System.out.println(c.getLinkMens().size());System.out.println(c.getLinkMens());}// ----------------------------------------------------
        tx.commit();session.close();}

SQL:

Hibernate: selectcustomer0_.cust_id as cust_id1_0_,customer0_.cust_name as cust_nam2_0_,customer0_.cust_source as cust_sou3_0_,customer0_.cust_industry as cust_ind4_0_,customer0_.cust_level as cust_lev5_0_,customer0_.cust_linkman as cust_lin6_0_,customer0_.cust_phone as cust_pho7_0_,customer0_.cust_mobile as cust_mob8_0_ fromcst_customer customer0_
Customer [cust_id=7, cust_name=测试名称1]
Hibernate: selectlinkmens0_.lkm_cust_id as lkm_cus10_1_1_,linkmens0_.lkm_id as lkm_id1_1_1_,linkmens0_.lkm_id as lkm_id1_1_0_,linkmens0_.lkm_gender as lkm_gend2_1_0_,linkmens0_.lkm_name as lkm_name3_1_0_,linkmens0_.lkm_phone as lkm_phon4_1_0_,linkmens0_.lkm_email as lkm_emai5_1_0_,linkmens0_.lkm_qq as lkm_qq6_1_0_,linkmens0_.lkm_mobile as lkm_mobi7_1_0_,linkmens0_.lkm_memo as lkm_memo8_1_0_,linkmens0_.lkm_position as lkm_posi9_1_0_,linkmens0_.lkm_cust_id as lkm_cus10_1_0_ fromcst_linkman linkmens0_ wherelinkmens0_.lkm_cust_id in (selectcustomer0_.cust_id fromcst_customer customer0_)

2.关联属性懒加载(先查询联系人,跟据联系人反查顾客)

XML配置:

<?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.qlq.domain" ><class name="LinkMan" table="cst_linkman" ><id name="lkm_id"  ><generator class="native"></generator></id><property name="lkm_gender"  ></property><property name="lkm_name"  ></property><property name="lkm_phone"  ></property><property name="lkm_email"  ></property><property name="lkm_qq"  ></property><property name="lkm_mobile"  ></property><property name="lkm_memo"  ></property><property name="lkm_position"  ></property><!-- fetch 决定加载的sql语句select: 使用单表查询join : 多表查询 (会导致lazy失效)lazy  决定加载时机false: 立即加载proxy: 由customer的类级别加载策略决定.--><many-to-one name="customer" column="lkm_cust_id" class="Customer" fetch="select" lazy="proxy"></many-to-one></class>
</hibernate-mapping>

1.fetch为select,lazy为proxy,Customer类的lazy为true

测试代码:

    // 集合级别的关联// fetch:select 单表查询// lazy:proxy 代理,也就是由Customer的lazy属性决定是否懒加载//Customer的lazy为true
    @Testpublic void fun1() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
LinkMan linkMan = session.get(LinkMan.class, 5l);System.out.println("-------1------------");Customer customer = linkMan.getCustomer();System.out.println("-------2------------");System.out.println(customer);// 打印SQL// ----------------------------------------------------
        tx.commit();session.close();}

SQL:

Hibernate: selectlinkman0_.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_ fromcst_linkman linkman0_ wherelinkman0_.lkm_id=?
-------1------------
-------2------------
Hibernate: selectcustomer0_.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_ fromcst_customer customer0_ wherecustomer0_.cust_id=?
Customer [cust_id=9, cust_name=测试名称3]

2.fetch为select,lazy为proxy,Customer类的lazy为false

测试代码:

    // 集合级别的关联// fetch:select 单表查询// lazy:proxy 代理,也就是由Customer的lazy属性决定是否懒加载//Customer的lazy为false
    @Testpublic void fun2() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
        LinkMan linkMan = session.get(LinkMan.class, 5l);System.out.println("-------1------------");Customer customer = linkMan.getCustomer();System.out.println("-------2------------");System.out.println(customer);// 打印SQL// ----------------------------------------------------
        tx.commit();session.close();}

SQL:

Hibernate: selectlinkman0_.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_ fromcst_linkman linkman0_ wherelinkman0_.lkm_id=?
Hibernate: selectcustomer0_.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_ fromcst_customer customer0_ wherecustomer0_.cust_id=?
-------1------------
-------2------------
Customer [cust_id=9, cust_name=测试名称3]

3.fetch为join,lazy属性失效

代码:

    // 集合级别的关联// join 单表查询// lazy: 属性失效
    @Testpublic void fun3() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
        LinkMan linkMan = session.get(LinkMan.class, 5l);System.out.println("-------1------------");Customer customer = linkMan.getCustomer();System.out.println("-------2------------");System.out.println(customer);// 打印SQL// ----------------------------------------------------
        tx.commit();session.close();}

SQL:

Hibernate: selectlinkman0_.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_ fromcst_linkman linkman0_ left outer joincst_customer customer1_ on linkman0_.lkm_cust_id=customer1_.cust_id wherelinkman0_.lkm_id=?
-------1------------
-------2------------
Customer [cust_id=9, cust_name=测试名称3]

总结:

  为了提高效率.fetch的选择上应选择select. lazy的取值应选择 true. 全部使用默认值.

3.批量抓取策略(batch-size属性)

  此次略用于获取客户联系人的时候,一次抓取几个客户的联系人。此策略用于避免多次访问数据库,没有此策略是一次获取一个客户联系人,有了此策略可以一次获取多个客户的,减少访问数据库次数。

例如

<?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.qlq.domain" ><class name="Customer" table="cst_customer"><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: 5   抓取集合的数量为5.抓取客户的集合时,一次抓取几个客户的联系人集合.--><set name="linkMens" batch-size="5"><key column="lkm_cust_id" ></key><one-to-many class="LinkMan" /></set></class>
</hibernate-mapping>

测试代码:

    public void fun5() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();// ----------------------------------------------------
String hql = "from Customer";Query query = session.createQuery(hql);List<Customer> list = query.list();for (Customer c : list) {System.out.println(c.getLinkMens());}// ----------------------------------------------------
        tx.commit();session.close();}

SQL:

Hibernate: selectcustomer0_.cust_id as cust_id1_0_,customer0_.cust_name as cust_nam2_0_,customer0_.cust_source as cust_sou3_0_,customer0_.cust_industry as cust_ind4_0_,customer0_.cust_level as cust_lev5_0_,customer0_.cust_linkman as cust_lin6_0_,customer0_.cust_phone as cust_pho7_0_,customer0_.cust_mobile as cust_mob8_0_ fromcst_customer customer0_
Hibernate: selectlinkmens0_.lkm_cust_id as lkm_cus10_1_1_,linkmens0_.lkm_id as lkm_id1_1_1_,linkmens0_.lkm_id as lkm_id1_1_0_,linkmens0_.lkm_gender as lkm_gend2_1_0_,linkmens0_.lkm_name as lkm_name3_1_0_,linkmens0_.lkm_phone as lkm_phon4_1_0_,linkmens0_.lkm_email as lkm_emai5_1_0_,linkmens0_.lkm_qq as lkm_qq6_1_0_,linkmens0_.lkm_mobile as lkm_mobi7_1_0_,linkmens0_.lkm_memo as lkm_memo8_1_0_,linkmens0_.lkm_position as lkm_posi9_1_0_,linkmens0_.lkm_cust_id as lkm_cus10_1_0_ fromcst_linkman linkmens0_ wherelinkmens0_.lkm_cust_id in (?, ?, ?, ?, ?)
[LinkMan [lkm_id=4, lkm_gender=null, lkm_name=田七, lkm_phone=null, lkm_email=null, lkm_qq=null, lkm_mobile=null, lkm_memo=null, lkm_position=null, customer=Customer [cust_id=7, cust_name=测试名称1]], LinkMan [lkm_id=3, lkm_gender=null, lkm_name=王八, lkm_phone=null, lkm_email=null, lkm_qq=null, lkm_mobile=null, lkm_memo=null, lkm_position=null, customer=Customer [cust_id=7, cust_name=测试名称1]]]
[]
[LinkMan [lkm_id=5, lkm_gender=null, lkm_name=99, lkm_phone=null, lkm_email=null, lkm_qq=null, lkm_mobile=null, lkm_memo=null, lkm_position=null, customer=Customer [cust_id=9, cust_name=测试名称3]]]
[]
[]
Hibernate: selectlinkmens0_.lkm_cust_id as lkm_cus10_1_1_,linkmens0_.lkm_id as lkm_id1_1_1_,linkmens0_.lkm_id as lkm_id1_1_0_,linkmens0_.lkm_gender as lkm_gend2_1_0_,linkmens0_.lkm_name as lkm_name3_1_0_,linkmens0_.lkm_phone as lkm_phon4_1_0_,linkmens0_.lkm_email as lkm_emai5_1_0_,linkmens0_.lkm_qq as lkm_qq6_1_0_,linkmens0_.lkm_mobile as lkm_mobi7_1_0_,linkmens0_.lkm_memo as lkm_memo8_1_0_,linkmens0_.lkm_position as lkm_posi9_1_0_,linkmens0_.lkm_cust_id as lkm_cus10_1_0_ fromcst_linkman linkmens0_ wherelinkmens0_.lkm_cust_id in (?, ?, ?)

  通过SQL看出获取客户联系人的时候一次获取5个客户的联系人,最后一次由于没有五个客户所以会查询剩余3个客户的联系人。

问题:   no-session问题解决: 扩大session的作用范围.

  在懒加载的策略中,我们通常是在Service层打开事务、session,service代码执行完毕只会进行提交或者回滚。但是我们的对象(代理对象)经常放在request域中带到页面进行显示,也就是到了页面才使用对象(查询数据库),此时session已经关闭,如果使用了懒加载策略会报no-session异常。解决办法:过滤器扩大session作用范围(filter可以在请求执行前后都执行一些代码),如下图逻辑:

  其实SSH整合的时候spring已经做了过滤器来实现此功能,会在搭建SSH环境的时候介绍。

Hibernate延迟加载策略相关推荐

  1. hibernate 延迟加载问题探讨

    延迟初始化错误是运用Hibernate开发项目时最常见的错误.如果对一个类或者集合配置了延迟检索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于Session范围内)时,才能初始化它.如果在 ...

  2. hibernate 延迟加载(转载)

    http://blog.csdn.net/xc635960736/article/details/7049863(未找到原始的引文) Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默 ...

  3. Hibernate延迟加载

    1.类级别的延迟加载 1.     是通过session.load方法实现的      在映射文件中:       <class name="cn.itcast.hibernate71 ...

  4. Hibernate 延迟加载(一)

    1 延迟加载策略 Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术.这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录.通过延迟加载技术可以避免过多.过早地加载数据 ...

  5. hibernate数据检索策略

    hibernate框架提供的检索策略有立即检索.延迟检索.预先检索和批量检索. 帖子(Topic)与回复(Reply)之间是一对多的关联关系. Topic类: public class Topic { ...

  6. IT忍者神龟之hibernate 延迟加载问题探讨

    关于   lazy   机制: 延迟初始化错误是运用   Hibernate   开发项目时最常见的错误.如果对一个类或者集合配置了延迟检索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于S ...

  7. hibernate 延迟加载

    Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,实体所关联的实体默认也会被延迟加载.Hibernate 通过这种延迟加载来降低系统的内存开销,从而保证 Hiberna ...

  8. 一些关于Hibernate延迟加载的误区

    最近面试别人,正好出的笔试题中有道关于Hibernate延迟加载的问题,聊天过程中发现很多人对Hibernate的延迟加载有些理解误区,写 些东东在这里,希望对大家有所帮助. 首先是第一个误区:延迟加 ...

  9. 不同的Hibernate命名策略

    本文讨论了hibernate提供的不同命名策略,以及命名策略从hibernate 4中的hibernate.ejb.naming_strategy到hibernate 5中的hibernate.imp ...

最新文章

  1. 比特币现金BCH 硬分叉,能否突破$1500?
  2. [python] LDA处理文档主题分布及分词、词频、tfidf计算
  3. QMsgPack的用法DEMO
  4. python源码只有编译成二进制_Python源码包和二进制包(包含打包过程细节讲解)...
  5. 面向对象的一些基础概念
  6. ipython和pylab模式_为什么要使用IPython?
  7. worknc的后处理如何安装_这些压缩空气后处理问题,大部分人都没有关注到
  8. 适应adblock plus 规则的简单正则表达式匹配
  9. Windows7下IIS7.5的伪静态URL Rewrite安装配置和案例综合
  10. 146.LRU缓存机制
  11. SmartSens在ISSCC 2019 图像传感器技术领域报告会作开场报告,收录论文抢先披露
  12. 用阿里云短信服务--通过Web接口发送短信
  13. 30岁前,环游世界220天
  14. 小程序源码:王者战力查询,游戏扫码登录,王者巅峰信息查询等等支持流量主收益和CPS收益-多玩法安装简单
  15. 2008年8月6号,晴,今天天气已经变热了。少壮不努力,老大徒悲伤。 —— 汉乐府古辞《长歌行》
  16. Java温习——表达式expression
  17. Sublime Text 3 装了Anaconda 写Python代码出现框框的解决办法
  18. mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object完美解决方案
  19. S19文件格式详解(总结)以及与hex文件的互转
  20. 使用外链的方式让易班的轻应用更漂亮

热门文章

  1. 52单片机定时器2使用(C语言程序)
  2. 用VB无窗口透明Usercontrol编写透明浮动按钮
  3. VB中什么是类,类模块有什么作用
  4. 使链接在新窗口中打开
  5. XP命令合集(开始→运行→输入的命令集锦开始→运行→输入的命令集锦)
  6. 智能一代云平台(三十六):项目中如何做到避免传递依赖
  7. 大三学生独自破解逆天AI模型:我只是把撩妹的时间,都用来研究机器学习了...
  8. DeepMind和Unity合作,创建虚拟世界来训练AI
  9. 无人车创业正驶入分水岭
  10. 中国无人车第一案!百度状告景驰王劲:窃取机密,不还电脑,索赔5000万