> 文章列表 > mysql mybaits的update语句执行, 自定义返回值, 借助变量和<selectKey>

mysql mybaits的update语句执行, 自定义返回值, 借助变量和<selectKey>

mysql mybaits的update语句执行, 自定义返回值, 借助变量和<selectKey>

正常update语句返回受影响行数,有些业务场景下不太适用, 希望update后能返回影响行主键id或其他信息, 这样有利于后续继续处理数据

一、举例一个简单场景:

1.优惠券表coupon, 包含字段:主键id优惠券Code, 归属人user_id
2.业务需要提前生成1000张优惠券,插入数据表;
3.用户争抢优惠券,设置优惠券信息表coupon,填充归属人user_id

当不借助其他第三方功能(redis等)情况下,仅仅使用数据库处理

二、方法一:存在弊端,不建议

(1)用户请求接口,先查询优惠券表coupon, 筛选出归属人user_id等于null的数据,取出第一条
(2)再利用主键id, 利用update语句、去更新user_id

如果并发量大,多个请求可能同时拿到同一条数据,导致业务异常,如果进行业务加锁处理,大大降低吞吐量, 弊端太明显, 不可取

三、方法二:推荐

直接省去查询动作,直接update, 并且在update同时返回影响行的id

(1)mysql语法:

set @ids := "";UPDATE coupon
SET user_id = '1111111111111'
WHEREuser_id IS NULL
AND (SELECT @ids := IF (LENGTH(@ids) = 0, id, CONCAT(@ids, ",", id))
)
LIMIT 1  ;SELECT @ids;

核心逻辑:
1.在update语句中,where条件筛选时,将当前行id,赋值给变量暂存, update执行后,再查询出变量
2.更新时可能存在多行,返回多个id, 利用mysql内置函数, 拼接id, 用逗号隔开 IF (LENGTH(@ids) = 0, id, CONCAT(@ids, ",", id)

(2)mybaits处理:

mybaits的update标签无法直接查询变量再返回, 可以利用selectKey标签,将变量值重新赋值给update入参的parameterType,进行返回

1.定义modle,

@Data
public class UpdateCouponPo {/*** 用于接收更新行的主键id*/private String ids = "";private Long userId ;
}

2.定义Mapper

void updateCoupon(@Param("po") UpdateCouponPo po);

3.Mapper的xml实现

<update id="updateCoupon" parameterType="com.jzy.XXX.model.po.UpdateCouponPo" >set @ids := "";UPDATE couponSET user_id = #{po.userId}WHEREuser_id IS NULLAND (SELECT @ids := IF (LENGTH(@ids) = 0, id, CONCAT(@ids, ",", id)))LIMIT 1  ;<selectKey keyProperty='po.ids' resultType='java.lang.String' order='AFTER'>select @ids as ids;</selectKey>
</update>

4.调用Mapper

public void updateCoupon(Long userId){UpdateCouponPo po = new UpdateCouponPo();po.setUserId(userId);baseMapper.updateCoupon(po);String ids = po.getIds();String[] idArray = ids.split(",");
}