`

总结:Hibernate 2 通过外连接查询多张表的数据。

    博客分类:
  • Java
阅读更多
问题:

        在Hibernate中,我们经常会碰到多张表通过外键连接来查询表中的数据,需要用到<many-to-one></many-to-one>,<one-to-many></one-to-many>等连接,特别是表之间的连接多了,如果我们通过延迟加载,或立即加载的话。就要多发很多的sql查询语句。

例:

EcssFormula.hbm.xml:

xml 代码
  1. <class name="com.ecgit.ecss.data.EcssTFormula" table="ECSS_T_FORMULA" schema="ECCM">  
  2.     <id name="formulaid" type="java.lang.String">  
  3.         <column name="FORMULAID" length="50" />  
  4.         <generator class="uuid.hex" />  
  5.     id>  
  6.     <many-to-one name="ecssTFormulaRestrictByFp" class="com.ecgit.ecss.data.EcssTFormulaRestrict" outer-join="true">  
  7.         <column name="FP" length="50" />  
  8.     many-to-one>  
  9.     <many-to-one name="ecssTFormulaRestrictByFormularesultchildtype" class="com.ecgit.ecss.data.EcssTFormulaRestrict"  outer-join="true">  
  10.         <column name="FORMULARESULTCHILDTYPE" length="50" />  
  11.     many-to-one>  
  12.     <many-to-one name="ecssTFormulaRestrictByTp" class="com.ecgit.ecss.data.EcssTFormulaRestrict" outer-join="true" >  
  13.         <column name="TP" length="50" />  
  14.     many-to-one>  
  15.     <many-to-one name="ecssTFormulaRestrictByPro" class="com.ecgit.ecss.data.EcssTFormulaRestrict" outer-join="true" >  
  16.         <column name="PRO" length="50" />  
  17.     many-to-one>  
  18.     <many-to-one name="ecssTFormulaRestrictByCl" class="com.ecgit.ecss.data.EcssTFormulaRestrict" outer-join="true" >  
  19.         <column name="CL" length="50" />  
  20.     many-to-one>  
  21.     <many-to-one name="ecssTFormulaRestrictByPer" class="com.ecgit.ecss.data.EcssTFormulaRestrict" outer-join="true">  
  22.         <column name="PER" length="50" />  
  23.     many-to-one>  
  24. class>  

EcssTFormulaRestrict.hbm.xml:

 

xml 代码
  1. <class name="com.ecgit.ecss.data.EcssTFormulaRestrict" table="ECSS_T_FORMULA_RESTRICT" schema="ECCM">  
  2.     <id name="restrictid" type="java.lang.String">  
  3.         <column name="RESTRICTID" length="50" />  
  4.         <generator class="uuid.hex" />  
  5.     id>  
  6.     <property name="appoint" type="java.lang.String">  
  7.         <column name="APPOINT" length="50" />  
  8.     property>  
  9.     <property name="isany" type="java.lang.String">  
  10.         <column name="ISANY" length="10" />  
  11.     property>  
  12.     <property name="exclude" type="java.lang.String">  
  13.         <column name="EXCLUDE" length="100" />  
  14.     property>  
  15.     <property name="limited" type="java.lang.String">  
  16.         <column name="LIMITED" length="100" />  
  17.     property>  
  18.     <property name="isnull" type="java.lang.String">  
  19.         <column name="ISNULL" length="10" />  
  20.     property>  
  21. class>  

ECSS_T_FORMULA与ECSS_T_FORMULA_RESTRICT表之间有六个多对一的连接。

因此如果我们不用外连接查询,要查询一个com.ecgit.ecss.data.EcssTFormula对象就要发送1+6(com.ecgit.ecss.data.EcssTFormulaRestrict)对象连接的语句。

在Hibernate 2中我们可以在<many-to-one></many-to-one>中用outer-join=true属性。

      outer-join关键字有3个值,分别是true,false,auto,默认是auto。

  1. true: 表示使用外连接抓取关联的内容,这里的意思是当使用load(EcssTFormula.class,“id“)时,Hibernate只生成一条SQL语句将EcssTFormula与他的连接EcssTFormulaRestrict全部初始化。
  2. false:表示不使用外连接抓取关联的内容,当load(EcssTFormula.class,“id“)时,Hibernate生成两条SQL语句,一条查询EcssTFormula表,另5条查询EcssTFormulaRestrict表。这样的好处是可以设置延迟加载,此处要将EcssTFormulaRestrict类设置为lazy=true。
  3. auto:具体是ture还是false看hibernate.cfg.xml中的配置

注意:如果使用HQL查询OrderLineItem,如 from EcssTFormulao where o.id='id',总是不使用外部抓取,及outer-join失效

这样的话我们就不能通过外连接来查询了。

那么我们可以直接在HQL语句中用 left join 来强制实现外连接查询。

java 代码
  1. public List findByProperty(String propertyName, Object value)   
  2.             throws SorcererException {   
  3.         log.debug("finding EcssTFormula instance with property: "  
  4.                 + propertyName + ", value: " + value);   
  5.         List list = new ArrayList();   
  6.         try {   
  7.             Session session = this.getSession();   
  8.             String queryString = "from EcssTFormula as formula left join formula.ecssTFormulaRestrictByFp , formula.ecssTFormulaRestrictByFormularesultchildtype" +   
  9.                     " , formula.ecssTFormulaRestrictByTp , formula.ecssTFormulaRestrictByPro , formula.ecssTFormulaRestrictByPer , formula.ecssTFormulaRestrictByCl where formula."  
  10.                     + propertyName + "=:"+propertyName;   
  11.             Query queryObject = session.createQuery(queryString);   
  12.             queryObject.setParameter(propertyName, value);   
  13.             List tempList = queryObject.list();   
  14.             for(int i=0;i
  15.                 list.add(((Object[])tempList.get(i))[0]);   
  16.             }   
  17.             log.debug("size:"+list.size());   
  18.             this.closeSessionIfNecessary(session);   
  19.         } catch (RuntimeException re) {   
  20.             log.error("find by property name failed", re);   
  21.             throw new SorcererException("获得公式失败", re);   
  22.   
  23.         } catch (Exception e) {   
  24.             e.printStackTrace();   
  25.             throw new SorcererException("获得公式失败", e);   
  26.         }   
  27.         return list;   
  28.     }  

 tempList 中存放的是一个Object数组,Object[7],Object[0]为EcssTFormula的实例,后面的六个是EcssTFormulaRestrict的实例。这样查询的语句只是一个sql语句:

 

sql 代码
  1. Hibernate: select this.FORMULAID as FORMULAID6_, this.FP as FP6_, this.FORMULARE   
  2. SULTCHILDTYPE as FORMULAR3_6_, this.TP as TP6_, this.PRO as PRO6_, this.CL as CL   
  3. 6_, this.PER as PER6_, this.CALCULATEID as CALCULAT8_6_, this.FORMULANAME as FOR  
  4. MULAN9_6_, this.FORMULATYPE as FORMULA10_6_, this.FORMULARESULTTYPE as FORMULA11   
  5. _6_, this.FORMULAPRECISION as FORMULA12_6_, this.FORMULAMARKETDATE as FORMULA13_   
  6. 6_, this.FORMULADATETYPE as FORMULA14_6_, this.DEFAULTVALUE as DEFAULT15_6_, thi   
  7. s.ISCALCULATE as ISCALCU16_6_, this.ISSYSTEMFORMULA as ISSYSTE17_6_, this.ISCONT   
  8. ACTID as ISCONTA18_6_, this.FORMULACONTENT as FORMULA19_6_, this.USERCONTENT as  
  9. USERCON20_6_, ecsstformu1_.RESTRICTID as RESTRICTID0_, ecsstformu1_.APPOINT as A   
  10. PPOINT0_, ecsstformu1_.ISANY as ISANY0_, ecsstformu1_.EXCLUDE as EXCLUDE0_, ecss   
  11. tformu1_.LIMITED as LIMITED0_, ecsstformu1_.ISNULL as ISNULL0_, ecsstformu2_.RES   
  12. TRICTID as RESTRICTID1_, ecsstformu2_.APPOINT as APPOINT1_, ecsstformu2_.ISANY a   
  13. s ISANY1_, ecsstformu2_.EXCLUDE as EXCLUDE1_, ecsstformu2_.LIMITED as LIMITED1_,   
  14.  ecsstformu2_.ISNULL as ISNULL1_, ecsstformu3_.RESTRICTID as RESTRICTID2_, ecsst   
  15. formu3_.APPOINT as APPOINT2_, ecsstformu3_.ISANY as ISANY2_, ecsstformu3_.EXCLUD   
  16. as EXCLUDE2_, ecsstformu3_.LIMITED as LIMITED2_, ecsstformu3_.ISNULL as ISNULL  
  17. 2_, ecsstformu4_.RESTRICTID as RESTRICTID3_, ecsstformu4_.APPOINT as APPOINT3_,   
  18. ecsstformu4_.ISANY as ISANY3_, ecsstformu4_.EXCLUDE as EXCLUDE3_, ecsstformu4_.L   
  19. IMITED as LIMITED3_, ecsstformu4_.ISNULL as ISNULL3_, ecsstformu5_.RESTRICTID as  
  20.  RESTRICTID4_, ecsstformu5_.APPOINT as APPOINT4_, ecsstformu5_.ISANY as ISANY4_,   
  21.  ecsstformu5_.EXCLUDE as EXCLUDE4_, ecsstformu5_.LIMITED as LIMITED4_, ecsstform   
  22. u5_.ISNULL as ISNULL4_, ecsstformu6_.RESTRICTID as RESTRICTID5_, ecsstformu6_.AP   
  23. POINT as APPOINT5_, ecsstformu6_.ISANY as ISANY5_, ecsstformu6_.EXCLUDE as EXCLU   
  24. DE5_, ecsstformu6_.LIMITED as LIMITED5_, ecsstformu6_.ISNULL as ISNULL5_ from EC   
  25. CM.ECSS_T_FORMULA this, ECCM.ECSS_T_FORMULA_RESTRICT ecsstformu1_, ECCM.ECSS_T_F   
  26. ORMULA_RESTRICT ecsstformu2_, ECCM.ECSS_T_FORMULA_RESTRICT ecsstformu3_, ECCM.EC   
  27. SS_T_FORMULA_RESTRICT ecsstformu4_, ECCM.ECSS_T_FORMULA_RESTRICT ecsstformu5_, E   
  28. CCM.ECSS_T_FORMULA_RESTRICT ecsstformu6_ where 1=1 and this.FP=ecsstformu1_.REST   
  29. RICTID(+) and this.FORMULARESULTCHILDTYPE=ecsstformu2_.RESTRICTID(+) and this.TP   
  30. =ecsstformu3_.RESTRICTID(+) and this.PRO=ecsstformu4_.RESTRICTID(+) and this.CL=   
  31. ecsstformu5_.RESTRICTID(+) and this.PER=ecsstformu6_.RESTRICTID(+)  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics