Hibernate的多表查询

本文介绍如何利用Hibernate的映射文件简化多表联合查询的过程,通过具体案例展示如何仅使用对象导航来获取跨表的数据,避免复杂的SQL语句。
    经常看到有人发帖寻求Hibernate多表联合查询的问题,又是inner join,又是left,又是right。我比较死板,看到这些头很大。我觉得,又了Hibernate的映射文件,根本就没必要搞联合查询,至少不用写那么累赘的SQL语句。无可否认,SQL语句已经在我们的脑海中根深蒂固。
    现在做的项目,经常要用到多表查询,而且用到的表,一般不是三个,有的时候需要更多,但是,用了映射文件的OneToMany,其实查询也可以很简单!
例子一:
TABLE 1:IMPLANTBT,记录病人植管信息
TABLE 2:FOLLOWUP_PERFORM_BT,记录病人随访结果
TABLE 3: HER_MT,记录病人的电子病历信息
他们的映射文件片段分别如下:
/* ImPlantBt.hbm.xml */
<hibernate-mapping package="com.cdms.dataaccess.model">
    
<class
        
name="ImplantBt"
        table
="IMPLANT_BT"
    
>
        
<id
            
name="id"
            type
="integer"
            column
="IMPLANT_ID"
        
>
            
<generator class="sequence"><param name="sequence">S_implant_bt</param></generator>
        
</id>

        
<property
            
name="implantDate"
            column
="IMPLANT_DATE"
            type
="date"
            not-null
="false"
            length
="7"
        
/>
        
<many-to-one
            
name="followupPerform"
            column
="FOLLOWUP_PERFORM_ID"
            class
="FollowupPerfInfoBt"
            not-null
="false"
        
>
        
</many-to-one>


    
</class>    
</hibernate-mapping>
/*FollowupPerformBt.hbm.xml */
<hibernate-mapping package="com.cdms.dataaccess.model">
    
<class name="FollowupPerfInfoBt" table="FOLLOWUP_PERF_INFO_BT">
        
<id name="id" type="integer" column="FOLLOWUP_PERFORM_ID">
            
<generator class="sequence">
                
<param name="sequence">S_followup_perf_info_bt</param>
            
</generator>
        
</id>

        
<many-to-one name="ehr" column="EHR_ID" class="EhrMt" not-null="false"></many-to-one>


        
<set inverse="true" lazy="true" name="implant">
            
<key column="FOLLOWUP_PERFORM_ID" />
            
<one-to-many class="ImplantBt" />
        
</set>

    
</class>
</hibernate-mapping>

 

/*EhrMt.hbm.xml */
<hibernate-mapping package="com.cdms.dataaccess.model">
    
<class name="EhrMt" table="EHR_MT" dynamic-update="true" dynamic-insert="true">
        
<id name="id" type="integer" column="EHR_ID">
            
<generator class="sequence">
                
<param name="sequence">S_ehr_mt</param>
            
</generator>
        
</id>

        
    
    
</class>
</hibernate-mapping>

[任务]根据电子病历ID查询植管记录中的植管时间ImplantBt .implantDate

ImplantBt映射文件中有followupPerform

他实际上对应于一条随访结果记录,因此,用Implant.followupPerform就可以得到相应的随访结果记录,同理,Implant.followupPerform.ehr.id则得到了与Implant中记录对应的电子病历的ID号,因此,查询代码可以这样写:
try {
            Query q 
= s
                    .createQuery(
"select a.implantDate from  ImplantBt  a where a.followupPerform.ehr.id=:ehrid");
            q.setInteger(
"ehrid",ehrid);
            d
=(Date)q.uniqueResult();
            System.err.println(
"    d=   "+d);
            
return d;
        }
 catch (Exception e) {
            e.printStackTrace();
        }
 finally {
            DAOHelper.closeSession(s);
        }

 
再看下面例子!
VIEW 1:VEMBER
TABLE 1:EHR_MT
TABLE 2: EMP_INFO1_ST
对应的映射文件片段如下:
/* VMember,hbm.xml */
<hibernate-mapping package="com.cdms.dataaccess.model">
    
<class name="VMember" table="V_MEMBER">
        
<id name="id" type="integer" column="MEMBER_INFO1_ID">
            
<generator class="sequence">
                
<param name="sequence">S_member_info1_st</param>
            
</generator>
        
</id>
        
<many-to-one name="primaryNurse" column="PRIMARY_NURSE_ID" class="EmpInfo1St" not-null="false" fetch="join"></many-to-one>
        
<many-to-one name="ehr" column="EHR_ID" class="EhrMt" not-null="false" fetch="join"></many-to-one>

    
</class>
</hibernate-mapping>
/* EmpInfo1St.hbm.xml */
<hibernate-mapping package="com.cdms.dataaccess.model">
    
<class name="EmpInfo1St" table="EMP_INFO1_ST">
        
<id name="id" type="integer" column="EMP_INFO1_ID">
            
<generator class="sequence">
                
<param name="sequence">S_emp_info1_st</param>
            
</generator>
        
</id>
        
<property name="name" column="NAME" type="string" not-null="true" length="10" />
        

        
<set name="memberInfo1StsByprimaryNurse" inverse="true" lazy="true">
            
<key column="EMP_INFO1_ID" />
            
<one-to-many class="MemberInfo1St" />
        
</set>
    
</class>
</hibernate-mapping>

 

/* EhrMt.hbm.xml */
<hibernate-mapping package="com.cdms.dataaccess.model">
    
<class name="EhrMt" table="EHR_MT" dynamic-update="true" dynamic-insert="true">
        
<id name="id" type="integer" column="EHR_ID">
            
<generator class="sequence">
                
<param name="sequence">S_ehr_mt</param>
            
</generator>
        
</id>
    
</class>
</hibernate-mapping>

  [任务]根据电子病历ID查询病人的责任护士名字。

首先,责任护士名字在表EMP_INFO1_ST中,电子病历ID在表EHR_MT中。用视图VMEMBER把他们联系起来!

查询代码如下:
try {
            System.err.println(
"ehrid="+ehrid);
            Query q 
= s
            .createQuery(
"select a.primaryNurse.name  from  VMember  a where a.ehr.id=:ehrid");
    q.setInteger(
"ehrid",ehrid);
            d
=(String)q.uniqueResult();
            System.err.println(
"    d=   "+d);
            
return d;
        }
 catch (Exception e) {
            e.printStackTrace();
        }
 finally {
            DAOHelper.closeSession(s);
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值