【Hibernate的HQL多表聯合查詢使用left join方式】


Hibernate不支持left join帶on的條件查詢。

  解決辦法:使用原生SQL或者使用HQL方式需要修改hbm文件(如果項目中大部分不適用級聯配置情況下)

  需求是查詢網絡信息,網絡信息中關聯了分區、網絡IP(1個網絡--N個網絡IP),網橋信息。

  HQL:

  public void queryVnets(Page page) {

  StringBuffer hql = new StringBuffer();

  hql.append("select new Map(vn.id as id, vn.vnName as vnName, b.name as vnType, ");

  hql.append("vn.vnIptype as vnIptype, vn.vnIp as vnIp,vn.vnNat as vnNat, vn.vnFlag as vnFlag, ");

  hql.append("vn.vnetFlag as vnetFlag, (case when sum(vmvn.state)='0' then 0 else 1 end) as vnState, ");

  hql.append("vn.useType as useType, vn.createTime as createTime, ");

  hql .append("zone.oneName as oneName, zone.oneHypervisor as oneHypervisor, zone.oneSeq as oneSeq) ");

  hql.append("from VnetTable vn, ZoneTable zone, BridgeTable b ");

  hql.append("left join fetch vn.VnTables vmvn where zone.id = vn.zoneId and vn.vnType = b.id ");

  … …

  hql.append(" group by vn.id");

  if (vnState != null && !"".equals(vnState)) {

  if ("0".equals(vnState)) {

  hql.append(" having sum(vmvn.state)=0");

  } else if ("1".equals(vnState)) {

  hql.append(" having sum(vmvn.state)!=0");

  }

  }

  }

  hbm配置文件:

  <?xml version="1.0" encoding="utf-8"?>

  <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

  "hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

  <!--

  Mapping file autogenerated by MyEclipse Persistence Tools

  -->

  <hibernate-mapping>

  <class name="com.base.mapping.VnetTable" table="vnet_table" >

  <id name="id" type="java.lang.String">

  <column name="ID" length="32" />

  <generator class="uuid.hex" />

  </id>

  <property name="vnId" type="java.lang.Long">

  <column name="VN_ID">

  <comment>創建虛擬網絡時得到的ID</comment>

  </column>

  </property>

  …

  <property name="zoneId" type="java.lang.String">

  <column name="ZONE_ID" length="32">

  <comment>分區ID</comment>

  </column>

  </property>

  <property name="vlanId" type="java.lang.Integer">

  <column name="VLAN_ID">

  <comment>VLAN_ID</comment>

  </column>

  </property>

  <set name="vnTables" lazy="false" order-by="id asc" inverse="false" fetch="join" cascade="all">

  <key column="VN_NID"/>

  <one-to-many class="com.base.mapping.VnTable"/>

  </set>

  </class>

  </hibernate-mapping>

  理解inverse和cascade,

  總結:

  <one-to-many>中,建議inverse="true",由"many"方來進行關聯關系的維護

  <many-to-many>中,只設置其中一方inverse="false",或雙方都不設置

  Cascade,通常情況下都不會使用。特別是刪除,一定要慎重。

  操作建議

  一般對many-to-one和many-to-many不設置級聯,這要看業務邏輯的需要;對one-to-one和one-to-many設置級聯。

  many-to-many關聯關系中,一端設置inverse="false",另一端設置為inverse="true".在one-to-many關聯關系中,設置inverse="true",由多端來維護關系表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM