Hibernate的HQL多表联合查询使用left join方式

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  endas 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"
"http://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,可以参考:http://blog.csdn.net/wkcgy/article/details/6271321
总结: 
<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”,由多端来维护关系表










你可能感兴趣的:(Hibernate的HQL多表联合查询使用left join方式)