天天看點

Mybatis一對多查詢、一對一查詢、一對多一對一混合查詢

最近開發進度進入平緩階段,根據經驗,這個時候正式調整優化的好時機,不然到後期做優化會很麻煩,于是靜下心來琢磨對資料通路這塊的優化問題。

項目已經開發了有将近兩個月了,各種需求的變更導緻資料庫已經被改了N個版本了(移動網際網路的痛)。建表的時候考慮到解耦和後期二次開發的問題就沒有在資料庫裡做外鍵關聯,把關聯放到程式裡做邏輯關聯。太多的關聯查詢已經把已經寫好的代碼改的面目全非了,于是就考慮在sql查詢的時候直接把所有一對多,一對一的關聯資訊全部查詢出來。查閱了下之前前輩寫的代碼,結果發現前輩隻寫了一半就沒有寫了,後面都沒有使用那段代碼查詢。沒辦法,那就隻能靠自己摸索了,好了背景交代完畢,開寫:

先從首頁入手,大緻的表結構我畫了一個結構圖,我要查詢的是動态表,順帶要一對多的查詢出動态對應的圖檔List及其中每個圖檔對應的Marker标記List和動态對應的評論List及其中每個評論人和回複人的使用者資訊,是以整個結構是一對多====》一對多===》一對一

Mybatis一對多查詢、一對一查詢、一對多一對一混合查詢

1、一對多查詢,下面引用别人已經寫好的demo來做筆記

一對多中的"一"
<mapper namespace="dao.mapper.ClassMapper">
 
    <resultMap id="classResultMap" type="Classes">
        <id property="classid" column="classid1" />
        <result property="classname" column="classname" />
        <result property="teacherid" column="teacherid2" />
        <collection property="studentList" column="classid" javaType="ArrayList" ofType="Student" select="StudentDao.getStudentByClassID" />
    </resultMap>
     
    <select id="selectAllByClassId" parameterType="int" resultMap="classResultMap">
        select * from class c where c.classid = #{classid};
    </select>
</mapper>
 
 
一對多中的"多"
 
<mapper namespace="StudentDao">
 
    <resultMap type="Student" id="studentResultMap">
        <id property="studentid" column="studentid" />
        <result property="studentname" column="studentname" />
    </resultMap>
     
    <!-- 查詢學生list,根據班級id -->
    <select id="getStudentByClassID" parameterType="String" resultMap="studentResultMap">
        select *from student st WHERE st.classid = #{classid1}
    </select>
</mapper>
           

除了這種寫法外,還有另外一種就是把兩個寫在一個xml裡,但是看起來感覺很混亂,不是我喜歡的風格。上面代碼裡的class就是我的動态表,student就是我的動态圖檔表,一個班裡有很多學生相當于我的一個動态有很多圖檔。在class加一個studenList字段來映射查詢出來的結果,classid可以很明顯的看出是取出結果裡的一個值,傳給getStudenByClassId,這樣就是在A.xml裡調用了B.xml裡的這個查詢方法,這段執行完成後在傳回的結果裡可以看到studenList裡已經有值了,而且跟資料庫裡的記錄是一直的,就說明這個一對多的查詢成功了。

2、一對一查詢,這個就更簡單了,同樣引用一段Demo代碼

<mapper namespace="dao.mapper.ClassMapper">
 
    <resultMap id="classResultMap" type="Classes">
        <id property="classid" column="classid1" />
        <result property="classname" column="classname" />
        <result property="teacherid" column="teacherid2" />
        <association property="teacher" column="teacherid" javaType="Teacher" select="getTeacher" />
<!--         <association property="teacher" column="teacherid" javaType="Teacher" select="dao.mapper.TeacherMapper.getTeacher" />  兩個XML檔案之間調用 -->
    </resultMap>
     
    <select id="selectAllByClassId" parameterType="int" resultMap="classResultMap">
        select * from class c where c.classid = #{classid};
    </select>
     
    <select id="getTeacher" parameterType="int" resultType="teacher">
        select * from teacher tt where tt.teacherid = #{teacherid2}
    </select>
     
     
</mapper>
           

一對一的查詢也可以用兩種方法,這個裡面把兩個xml之間調用的方法注釋掉了,用的是在一個xml裡做一對一的查詢,大緻的原理跟上面一樣,要注意是兩個類型是collection一個是association

3、一對多、一對一混合使用,上面兩個都整出來了,這個就更不是問題了,在一對多裡調用多的那個xml裡使用一對一。反之一樣。