读书人

hibernate的一对多时及时抓取策略

发布时间: 2012-10-16 09:57:37 作者: rapoo

hibernate的一对多时即时抓取策略
组织机构是一颗树型机构,一个父类对应多个子类。该对象的xml文件为

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping>  <class table="g_organization" name="com.going.platform.model.Organization">    <cache usage="read-write" region="com.going.platform.model.Organization"/>          <id access="field" name="id" type="java.lang.String" column="ID" length="32">      <generator type="string" length="50" not-null="true">              <column name="ORGANIZATION_NAME">                  <comment>机构名称</comment>              </column>          </property>        <property name="description" type="string" length="200">              <column name="DESCRIPTION">                  <comment>职能描述</comment>              </column>          </property>             <many-to-one column="PID" access="field" name="parent" not-found="ignore"/>              <set inverse="true" access="field" name="childern"  cascade="save-update,persist" order-by="ORDER_NUM">          <key column="PID"/>          <one-to-many type="string" length="20">              <column name="ORGANIZATION_TEL">                  <comment>部门电话</comment>              </column>          </property>          <property name="orderNum" type="java.lang.Integer">              <column name="ORDER_NUM" length="5">                  <comment>排序号</comment>              </column>          </property>   </class></hibernate-mapping>

形成机构树时,需要查询出所有节点,并且会根据节点来获取子节点。所以应该采用即时抓取。
方法一:设置lazy为false 也就是即时抓取
使用getHibernateTemplate().loadAll(Organization.class);能达到目的但会发出n+1条sql语句
  select        this_.ID as ID0_0_,        this_.ORGANIZATION_NAME as ORGANIZA2_0_0_,        this_.DESCRIPTION as DESCRIPT3_0_0_,        this_.PID as PID0_0_,        this_.ORGANIZATION_TEL as ORGANIZA5_0_0_,        this_.ORDER_NUM as ORDER6_0_0_     from        g_organization this_Hibernate:     select        childern0_.PID as PID1_,        childern0_.ID as ID1_,        childern0_.ID as ID0_0_,        childern0_.ORGANIZATION_NAME as ORGANIZA2_0_0_,        childern0_.DESCRIPTION as DESCRIPT3_0_0_,        childern0_.PID as PID0_0_,        childern0_.ORGANIZATION_TEL as ORGANIZA5_0_0_,        childern0_.ORDER_NUM as ORDER6_0_0_     from        g_organization childern0_     where        childern0_.PID=?     order by        childern0_.ORDER_NUM。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

第一条sql查询出所有记录,接下来会发出n条记录来获取所有相关的子记录。查询时间大概
20:26:18,105 INFO OrganizationBoTest:51 - *******发费时间******203

所以可以看出这种方式并不是最佳选择。
方法二: 设置抓取策略fetch="join" 并loadAll时只发送一条sql语句 fetch="join"只对load和get方法 还有就是条件查询会起作用,而对hsql的查询是不会有影响的
   select        this_.ID as ID0_1_,        this_.ORGANIZATION_NAME as ORGANIZA2_0_1_,        this_.DESCRIPTION as DESCRIPT3_0_1_,        this_.PID as PID0_1_,        this_.ORGANIZATION_TEL as ORGANIZA5_0_1_,        this_.ORDER_NUM as ORDER6_0_1_,        childern2_.PID as PID3_,        childern2_.ID as ID3_,        childern2_.ID as ID0_0_,        childern2_.ORGANIZATION_NAME as ORGANIZA2_0_0_,        childern2_.DESCRIPTION as DESCRIPT3_0_0_,        childern2_.PID as PID0_0_,        childern2_.ORGANIZATION_TEL as ORGANIZA5_0_0_,        childern2_.ORDER_NUM as ORDER6_0_0_     from        g_organization this_     left outer join        g_organization childern2_             on this_.ID=childern2_.PID     order by        childern2_.ORDER_NUM

发费时间大概为
20:28:01,450 INFO OrganizationBoTest:51 - ********发费时间*****178
但存在一个问题就是,对于许多其他查询应用可能不会操作子记录,也就没有立即抓取子节点的必要,而且这样会浪费内存。

读书人网 >软件架构设计

热点推荐