【MyBatis】collection一對多查詢
阿新 • • 發佈:2018-12-21
最近專案中有這樣一種需求,有一張園區表t_zone;一張圖片表t_picture,一個園區可能對應好幾張圖片(可以把t_zone理解為訂單,t_picture理解為商品,一張訂單可能對應好幾件商品)
t_zone實體
public class Zone extends BaseEntity { private String id; private String name;//園區名稱 private List<Picture> pictureList;//對應的照片集合 public String getId() { return id; } public void setId(String name) { this.id= id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Picture> getPictureList() { return pictureList; } public void setPictureList(List<Picture> pictureList) { this.pictureList = pictureList; } public String getObjId() { return objId; } public void setObjId(String objId) { this.objId = objId; } }
t_picture對應實體:
public class Zone extends BaseEntity { private String id; private String url;//照片地址 private String objId; //對應園區id public String getId() { return id; } public void setId(String name) { this.id= id; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }
方法一:
一開始我是這樣寫的:先把對應的園區查出來,然後再根據園區id去查詢對應的圖片t_picture,這樣就查詢了兩次資料庫:
Mapper:
<resultMap type="com.jdy.model.Zone" id="zoneResultMap"> <result property="id" column="id"/> <result property="name" column="name"/> </resultMap> <select id="selectZone" resultMap="zoneResultMap" parameterType="java.util.Map"> SELECT t1.* FROM t_zone t1 where <if test="id !=null and id !=''"> t1.id=#{id} </if> </select>
查詢:
list = this.mapper.selectZone(param);
for (Zone vo : list) {
//查詢照片牆
pictureList = this.pictureService.selectByTypeAndObjId(PictureType.ZONE_PIC.getValue(), vo.getId());
vo.setPictureList(pictureList);
}
(其實這舉的例子有點不太好,因為查詢園區返回的是個集合)
方法二(collection):
專案完成後偶然得知mybatis中collection可以解決一對多查詢,就改寫程式碼,改寫後的程式碼對資料庫進行一次查詢就可以得到想要的結果:
Mapper:
<resultMap type="com.jdy.model.Zone" id="zoneResultMap">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--proerty對應實體中定義的list集合,ofType對應實體-->
<collection property="pictureList" ofType="com.jdy.model.Picture" >
<!--之所以改變列名稱,是因為如果查詢時兩張表的id都要查詢,這時如果不改變重複欄位的其中一個欄位名稱,就會報重複欄位錯誤-->
<id column="picId" property="id" />
<result column="type" property="type" />
<result column="obj_id" property="objId" />
<result column="table_name" property="tableName" />
<result column="url" property="url" />
</collection>
</resultMap>
<select id="selectZone" resultMap="zoneResultMap" parameterType="java.util.Map">
SELECT t1.*, t2.id 'picId',t2.url
FROM
t_zone t1,t_picture t2
where
t1.id=t2.obj_id
<if test="id !=null and id !=''">
t1.id=#{id}
</if>
</select>
查詢:
list = this.mapper.selectZoneVoPage(param);
兩種方法效能對比:
因為資料庫資料不多,所以就將增加了查詢次數
耗時(ms) | 10次 | 50次 | 100次 | 1000次 | ||||
---|---|---|---|---|---|---|---|---|
方法 | 方法一 | 方法二 | 方法一 | 方法二 | 方法一 | 方法二 | 方法一 | 方法二 |
總耗時 | 5190 | 837 | 6829 | 3984 | 12642 | 9017 | 130017 | 94880 |
平均耗時 | 519.00 | 83.70 | 136.58 | 79.7 | 126.42 | 90.17 | 130.02 | 94.88 |
通過對比,可看出方法二用collection明顯比方法一效能要好,耗時少。如果考慮大資料的,可能效能體現的就明顯了。