【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明显比方法一性能要好,耗时少。如果考虑大数据的,可能性能体现的就明显了。

MyBatis中进行一对多查询时,可以使用`<collection>`标签来映射子查询的结果集,并通过`select`属性指定子查询的SQL语句。如果您想要只对主表进行分组,可以使用`<select>`标签来编写主查询的SQL语句,并在子查询中使用`where`子句限制子表的查询条件,以确保子表不受主表分组的影响。以下是一个示例: ``` <select id="selectOrder" resultMap="orderResultMap"> SELECT o.*, c.customer_name FROM orders o JOIN customers c ON o.customer_id = c.customer_id GROUP BY o.order_id </select> <resultMap id="orderResultMap" type="Order"> <id column="order_id" property="orderId"/> <result column="order_date" property="orderDate"/> <result column="customer_name" property="customerName"/> <collection property="items" ofType="OrderItem"> <id column="item_id" property="itemId"/> <result column="product_id" property="productId"/> <result column="quantity" property="quantity"/> <result column="price" property="price"/> <association property="product" javaType="Product"> <id column="product_id" property="productId"/> <result column="product_name" property="productName"/> <result column="unit_price" property="unitPrice"/> </association> <select id="selectItemByOrderId" resultMap="orderItemResultMap"> SELECT * FROM order_items WHERE order_id = #{orderId} </select> </collection> </resultMap> ``` 在上述示例中,`<select>`标签中的SQL语句只对主表`orders`进行了分组,而子表`order_items`的查询条件使用`WHERE`子句进行了限制,以确保子表不受主表分组的影响。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值