myBatis --關聯查詢

業務需求,須要查詢到的結果集以下html

結構分析java

1.查詢出全部的評論,即data[]裏面是一個list
sql

2.查出list中每一個評論id(即userObjectCmmtId)下面全部的子評論,即一對多的關係。數據庫

實現方法以下mybatis

1.接口層文件以下
dom


2.實現層文件以下學習


3.返回第一層bean以下ui

返回第二層bean
spa

4.xml文件以下(第一層)code

   <resultMap type="com.zhiji.caren.VO.CmmtRel" id="cmmtListMap">
        <result column="USER_PERSON_CMMT_ID" property="userObjectCmmtId"
            jdbcType="VARCHAR" />
        <result column="ROOT_USER_ID" property="rootUserId" jdbcType="INTEGER" />
        <result column="ROOT_USER_IMG" property="rootUserImg" jdbcType="VARCHAR" />
        <result column="ROOT_USER_NICKNAME" property="rootUserNickName"
            jdbcType="VARCHAR" />
        <result column="ROOT_CMMT_CONTENT" property="rootCmmtContent"
            jdbcType="VARCHAR" />
        <result column="ROOT_ADD_TIME" property="rootAddTime" jdbcType="VARCHAR" />
        <collection property="cmmtData" javaType="ArrayList"
            column="{rootCmmtId = USER_PERSON_CMMT_ID" select="getSubCmmtInfo" />
    </resultMap>
    
    <select id="selectCmmtList" resultMap="cmmtListMap">
        SELECT
        tupctui.USER_PERSON_CMMT_ID,
        tupctui.ROOT_USER_ID,
        tupctui.ROOT_USER_IMG,
        tupctui.ROOT_USER_NICKNAME,
        tupctui.ROOT_CMMT_CONTENT,
        tupctui.ROOT_ADD_TIME
        from
        (SELECT
        tupc.USER_PERSON_CMMT_ID,
        tupc.USER_ID AS ROOT_USER_ID,
        tui.USER_IMG AS
        ROOT_USER_IMG,
        tui.NICKNAME AS ROOT_USER_NICKNAME,
        tupc.CMMT_CONTENT AS
        ROOT_CMMT_CONTENT,
        tupc.ADD_TIME AS ROOT_ADD_TIME
        FROM
        t_user_person_cmmt tupc,t_user_info tui
        WHERE
        tupc.USER_ID = tui.USER_ID
        AND
        tupc.ROOT_CMMT_ID is NULL
        AND
        PERSON_ID = #{objectId,jdbcType =
        INTEGER}
        <if test="lastTime != null">
            AND
            tupc.ADD_TIME &lt;= #{lastTime}
        </if>
        ORDER BY ROOT_ADD_TIME DESC)
        tupctui
        LIMIT #{pageIndex}
    </select>

xml文件第二層以下

    <resultMap type="com.zhiji.caren.VO.CmmtRelChild" id="subCmmtMap">
        <result column="SUPER_CMMT_ID" property="superCmmtId" jdbcType="VARCHAR" />
        <result column="SUPER_USER_ID" property="superUserId" jdbcType="INTEGER" />
        <result column="SUPER_NICKNAME" property="superNickName"
            jdbcType="VARCHAR" />
        <result column="CHILD_USER_ID" property="childUserId" jdbcType="INTEGER" />
        <result column="CHILD_USER_NICKNAME" property="childUserNickName"
            jdbcType="VARCHAR" />
        <result column="CHILD_CMMT_CONTENT" property="childCmmtContent"
            jdbcType="VARCHAR" />
        <result column="USER_PERSON_CMMT_ID" property="childCmmtId"
            jdbcType="VARCHAR" />
    </resultMap>
    
    <select id="getSubCmmtInfo" resultMap="subCmmtMap">
        SELECT
        tupc.ROOT_CMMT_ID,
        tupc.SUPER_CMMT_ID,
        tupc.SUPER_USER_ID,
        tuii.NICKNAME as SUPER_NICKNAME,
        tupc.USER_ID AS CHILD_USER_ID,
        tui.NICKNAME AS CHILD_USER_NICKNAME,
        tupc.CMMT_CONTENT AS CHILD_CMMT_CONTENT,
        tupc.USER_PERSON_CMMT_ID,
        tupc.ADD_TIME AS CHILD_ADD_TIME
        FROM
        t_user_person_cmmt tupc
        LEFT JOIN
        t_user_info tui on
        tupc.USER_ID = tui.USER_ID
        LEFT JOIN
        t_user_info tuii
        on
        tupc.SUPER_USER_ID = tuii.USER_ID
        WHERE
        tupc.ROOT_CMMT_ID IS NOT NULL
        AND
        ROOT_CMMT_ID = #{rootCmmtId}
        ORDER BY CHILD_ADD_TIME
    </select>

總結:如上例子中用到了mybatis的collection,即

        <collection property="cmmtData" javaType="ArrayList"
            column="{rootCmmtId = USER_PERSON_CMMT_ID" select="getSubCmmtInfo" />

如今就這個點學習下寫一篇文章

//參考文章以下連接,真心講的不錯,好東西拿出來你們分享

http://www.cnblogs.com/xdp-gacl/p/4264440.html


1、一對一關聯查詢

假設A表(班級表,t_class)

c_id       c_name      teacher_id

1            一班           x

2            二班           x

假設B表(教師表,t_teacher)

t_id       t_name

1           張三

2           李四

如今業務需求:根據班級id查詢班級信息(查詢出該班級的老師信息,假設班級與教師一對一關係)

方法一:嵌套結果--聯表查詢,一次查詢得出結果

<!-- 使用resultMap映射實體類和字段之間的一一對應關係 -->
<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
     <id property="id" column="c_id"/>
     <result property="name" column="c_name"/>
     <association property="teacher" javaType="me.gacl.domain.Teacher">
             <id property="id" column="t_id"/>
            <result property="name" column="t_name"/>
     </association>    
</resultMap>        
<select id="getClass" parameterType="int" resultMap="ClassResultMap">         
        select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=#{id}     
</select>

備註:實際過程當中,我可能不會用到association那段,我在 me.gacl.domain.classes中定義屬性的時候,直接將班級屬性和老師屬性定義在一塊兒,這樣resultMap就能夠改寫成以下

<resultMap type="me.gacl.domain.ClassesAndTeacher" id="ClassResultMap">
     <id property="cid" column="c_id"/>
     <result property="name" column="c_name"/>
     <result property="tid" column="t_id"/>
     <result property="name" column="t_name"/>
</resultMap>

最後,仔細考慮下,仍是以爲分開要好些,由於班級bean和教師bean是兩個基礎bean,而我根據這個業務需求還須要從新定義一個混合bean,即浪費了一個bean。按理推之,若是每一個業務都須要關聯多張表,按照個人作法,即須要新建多個bean,按照第一種方法,則只須要關聯基礎bean就行。

方法二:嵌套查詢--屢次查詢得出結果      

<select id="getClass2" parameterType="int" resultMap="ClassResultMap">
        select * from class where c_id=#{id}
</select>

<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
     <id property="id" column="c_id"/>
     <result property="name" column="c_name"/>
     <association property="teacher" column="teacher_id" select="getTeacher"/>
 </resultMap>
 
 <select id="getTeacher" parameterType="int" resultType="me.gacl.domain.Teacher">
     SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
 </select>

備註:很明顯這是分兩次查詢,先用#{id}查詢班級信息,再用#{id}查詢教師信息。

總結:

MyBatis中使用association標籤來解決一對一的關聯查詢,association標籤可用的屬性以下:

property:對象屬性的名稱

javaType:對象屬性的類型

column:所對應的外鍵字段名稱

select:使用另外一個查詢封裝的結果


2、一對多關聯查詢

新的需求:根據班級id查詢出班級信息(包括教師,學生)。班級與教師一對一關係,班級與學生一對多關係。

如今須要在如上數據庫表的基礎上加上學生表

假設C表(學生表,t_student)

s_id       s_name         s_classId

1           小吳               x

2           小李               x

1.返回的結構以下

public class classInfo
{
        //班級id
        private int id;
        //班級名稱
        private String name;
        /**
        * class表中有一個teacher_id字段,因此在Classes類中定義一個teacher屬性,
        * 用於維護teacher和class之間的一對一關係,經過這個teacher屬性就能夠知道這個班級是由哪一個老師負責的
        **/
        private Teacher teacher;
        //使用一個List<Student>集合屬性表示班級擁有的學生
        private List<Student> students;
}

方法一:嵌套結果--聯表查詢,一次查詢得出結果

<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
     <id property="id" column="c_id"/>
     <result property="name" column="c_name"/>
     <association property="teacher" column="teacher_id" javaType="me.gacl.domain.Teacher">
         <id property="id" column="t_id"/>
          <result property="name" column="t_name"/>
     </association> 
     <!-- ofType指定students集合中的對象類型 -->
     <collection property="students" ofType="me.gacl.domain.Student">
          <id property="id" column="s_id"/>
          <result property="name" column="s_name"/>
     </collection>
</resultMap>

<select id="getClass" parameterType="int" resultMap="ClassResultMap">
        select * from class c, teacher t,student s where c.teacher_id=t.t_id and c.C_id=s.class_id and  c.c_id=#{id}
</select>

方法二:嵌套查詢

<select id="getClass" parameterType="int" resultMap="ClassResultMap">
        select * from class where c_id=#{id}
</select>        

<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
    <id property="id" column="c_id"/>
    <result property="name" column="c_name"/>
    <association property="teacher" column="teacher_id" javaType="me.gacl.domain.Teacher" select="getTeacher">
    </association>
    <collection property="students" ofType="me.gacl.domain.Student" column="c_id" select="getStudent">
    </collection>
</resultMap>

<select id="getTeacher" parameterType="int" resultType="me.gacl.domain.Teacher">
        SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}   
</select>
<select id="getStudent" parameterType="int" resultType="me.gacl.domain.Student">
        SELECT s_id id, s_name name FROM student WHERE class_id=#{id}
</select>

備註:

select * from class where c_id=#{id}  //#{id}是是實現層傳過來的值

select t_id,t_name from teacher where t_id=#{id}  //#{id}是上一個查詢獲得的teacher_id

select s_id,s_name from student where s_classId=#{id}  //#{id}是查詢到的c_id

總結:MyBatis中使用collection標籤來解決一對多的關聯查詢,ofType屬性指定集合中元素的對象類型。

相關文章
相關標籤/搜索