SSH与SSM学习之hibernate24——关联级别加载策略之属性关联加载策略

来源:互联网 发布:软件著作权 代理 编辑:程序博客网 时间:2024/05/16 11:21

  • SSH与SSM学习之hibernate24关联级别加载策略之属性关联加载策略
    • 一说明
    • 二laze和fetch的取值
    • 三Companyhbmxml配置
    • 四Employeehbmxml
    • 五测试代码
    • 六fetch为select proxy对应的对象取值为true测试
    • 七fetch为select proxy对应的对象取值为false测试
    • 八fetch为join测试
    • 九结论
    • 十no-session问题解决 扩大session的作用范围

SSH与SSM学习之hibernate24——关联级别加载策略之属性关联加载策略

一、说明

现在我们说的是 属性关联加载策略。和之前的 SSH与SSM学习之hibernate23——关联级别加载策略之集合关联加载策略 区别是

集合关联说的是:通过一个对象,获取到与它关联的集合数据,例如:通过公司,获取到员工(多个),这是一个集合

属性关联说的是:通过一个对象,获取到与它关联的对象数据,例如:通过员工,获取到公司(一个),这是一个属性

属性关联使用到的是 lazyfetch


二、laze和fetch的取值

lazy叫做懒加载或者延迟加载,取值如下

取值 说明 proxy: 由相关类的类级别加载策略决定(true或者false) false: 立即加载

fetch(抓取策略),决定加载策略.使用什么类型的sql语句加载集合数据。取值如下

取值 说明 select (默认值): 单表查询加载 join: 使用多表查询加载集合

下面我们分为二者的属性值两两配对(笛卡尔积)测试

第一行代表,lazy的取值

第一列代表,fetch的取值

proxy=tue proxy=false false select select,true select,false join join,ture join,false

我们知道 proxy 由相关类的类加载策略决定的,当proxy=false的时候,和 属性关联的lazy为false是一样的。

所以我们只需要验证下面的四种情况

proxy=tue proxy=false select select,true join join,ture

三、Company.hbm.xml配置

.....<hibernate-mapping package="com.qwm.hibernate03.domain" >    <!--测试中所说的 proxy的值为其实就是下面这个lazy的值-->    <class name="Company" table="tb_company" lazy="true">      .....    </class></hibernate-mapping>

四、Employee.hbm.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="com.qwm.hibernate03.domain" >    <class name="Employee" table="tb_employee" >        <id name="em_id"  >            <generator class="native"></generator>        </id>        <property name="name"  ></property>        <!--            fetch 决定加载的sql语句                select: 使用单表查询                join : 多表查询            lazy  决定加载时机                false: 立即加载                proxy: 由Company的类级别加载策略决定.         -->       <many-to-one name="company" column="com_id" class="Company" fetch="select" lazy="proxy"/>    </class></hibernate-mapping>

五、测试代码

/** * 所有的测试代码都是一样的 */@Testpublic void test1(){    Session session = HibernateUtils.openSession();    Transaction t = session.beginTransaction();    //----------------------------------------------    //获取到员工    Employee employee = session.get(Employee.class,1L);    System.out.println("-------------one--------------");    //获取到公司    Company c = employee.getCompany();    System.out.println("-------------two--------------");    //使用公司    System.out.println(c);    //----------------------------------------------    t.commit();    session.close();}

六、fetch为select, proxy对应的对象取值为true测试

Hibernate:     select        employee0_.em_id as em_id1_1_0_,        employee0_.name as name2_1_0_,        employee0_.com_id as com_id3_1_0_     from        tb_employee employee0_     where        employee0_.em_id=?-------------one---------------------------two--------------Hibernate:     select        company0_.id as id1_0_0_,        company0_.name as name2_0_0_     from        tb_company company0_     where        company0_.id=?Company{id=1, name='百鸟公司'}

fetch为select, proxy对应的对象取值为true。单表查询,使用了懒加载,属性只有使用的时候采取查询。


七、fetch为select, proxy对应的对象取值为false测试

Hibernate:     select        employee0_.em_id as em_id1_1_0_,        employee0_.name as name2_1_0_,        employee0_.com_id as com_id3_1_0_     from        tb_employee employee0_     where        employee0_.em_id=?Hibernate:     select        company0_.id as id1_0_0_,        company0_.name as name2_0_0_     from        tb_company company0_     where        company0_.id=?-------------one---------------------------two--------------Company{id=1, name='百鸟公司'}

fetch为select, proxy对应的对象取值为false。单表查询,直接查询数据。使用的时候,直接使用。


八、fetch为join测试

fetch为join的时候,lazy失效。使用多表查询,直接加载

Hibernate:     select        employee0_.em_id as em_id1_1_0_,        employee0_.name as name2_1_0_,        employee0_.com_id as com_id3_1_0_,        company1_.id as id1_0_1_,        company1_.name as name2_0_1_     from        tb_employee employee0_     left outer join        tb_company company1_             on employee0_.com_id=company1_.id     where        employee0_.em_id=?-------------one---------------------------two--------------Company{id=1, name='百鸟公司'}

九、结论

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


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

我们使用懒加载的策略,那么查询完成以后,session就关闭了。这个时候我们的使用到了属性,这个时候由于是懒加载,所以回去查询数据,然而session已经关闭了,那么就会抛出 no-session 的异常。

对于这个问题的解决,就是扩大session的作用范围。打开session和关闭session 都放到 Filter中。

image

阅读全文
0 0
原创粉丝点击