1. 程式人生 > >【MyBatis】collection一對多查詢

【MyBatis】collection一對多查詢

  最近專案中有這樣一種需求,有一張園區表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次
方法方法一方法二方法一方法二方法一方法二方法一方法二
總耗時51908376829398412642901713001794880
平均耗時519.0083.70136.5879.7126.4290.17130.0294.88

  通過對比,可看出方法二用collection明顯比方法一效能要好,耗時少。如果考慮大資料的,可能效能體現的就明顯了。