最近项目中有这样一种需求,有一张园区表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明显比方法一性能要好,耗时少。如果考虑大数据的,可能性能体现的就明显了。