如何用单条SQL更新唯一默认选项?MyBatis实现方案问询
单条SQL实现默认选项切换(SpringBoot+MyBatis实战)
问题1:能不能用单条SQL实现这个需求?
当然可以!MySQL支持在UPDATE语句中结合CASE WHEN条件分支,一次性完成两条更新操作——既把目标行设为默认,又把原默认行取消默认。这种方式原子性极强,不会出现“原默认取消了但新默认没设置成功”的中间异常状态。
问题2:具体怎么实现?
1. MySQL语句写法
先给你贴合测试数据的硬编码版本:
UPDATE option SET is_default = CASE WHEN id = 2 THEN 1 -- 将目标行id=2设为默认 WHEN id = 1 THEN 0 -- 将原默认行id=1取消默认 ELSE is_default -- 其他行保持原有状态 END WHERE name = 'a'; -- 仅操作name为'a'的分组数据
如果要做通用版(支持任意id切换默认,自动取消同分组的原默认),可以用子查询动态获取目标行的分组name,不用硬编码:
UPDATE option SET is_default = CASE WHEN id = ? THEN 1 ELSE 0 END WHERE name = (SELECT name FROM option WHERE id = ?);
执行时传入你要设为默认的记录id即可,适用于所有同分组的默认切换场景。
2. SpringBoot+MyBatis的实现方式
你的Option实体类已经用@Data注解简化了代码,注意如果在application.yml中开启MyBatis驼峰命名映射:
mybatis: configuration: map-underscore-to-camel-case: true
那么实体类的isDefault会自动对应数据库的is_default字段,无需额外配置结果映射。
第一步:Mapper接口定义
在OptionMapper接口中添加方法:
// 传入要设为默认的记录id,返回更新的行数 int updateDefaultOption(Integer targetId);
第二步:Mapper.xml配置
在对应的OptionMapper.xml中编写更新语句:
<update id="updateDefaultOption" parameterType="java.lang.Integer"> UPDATE option SET is_default = CASE WHEN id = #{targetId} THEN 1 ELSE 0 END WHERE name = (SELECT name FROM option WHERE id = #{targetId}) </update>
如果业务需要传递整个Option对象(比如同时用到id和name),也可以调整为:
int updateDefaultOption(Option option);
对应的xml修改为:
<update id="updateDefaultOption" parameterType="com.yourpackage.Option"> UPDATE option SET is_default = CASE WHEN id = #{id} THEN 1 ELSE 0 END WHERE name = #{name} </update>
调用时传入包含id和name的Option对象,就能完成默认选项的切换。
内容的提问来源于stack exchange,提问作者serapme
相关产品推荐
相关产品推荐

