小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
xdm,祝大家节日快乐!!👨💻
今天听《路过人间》演唱会Live限定版,爱上了一句歌词。
说来惭愧,人对爱只学会,视死如归。
1.业务需求
如下:
前台传给我一个 documentId
和List<UpdateDocumentAnswer>
对象给我。
执行条件:通过这个documentId
和List<UpdateDocumentAnswer>
中对UpdateDocumentAnswer.id
,修改document_answer
表的数据。
简单说:就是希望通过一条update语句,根据不同的条件改变多条需要改变的数据。
思考一:
我们先按照我们最简单的思维思考:
即拆成一句一句执行,for循环执行多条 update
语句。
update document_answer set where document_id=#{documentId} and id=#{answer.id}
这样写的话,我们的mapper层接收的参数,应该为:
int patchByDocumentId(@Param("documentId") Long documentId,@Param("answers") UpdateDocumentAnswer answers);
实现是可以实现的,但是因为需要执行多条update语句,效率是真的不敢恭维。
如果大家有尝试过,都会知道,for循环执行sql语句是真的要不得的。一条普通的sql,我们都要优化完再优化,更别说一个方法要执行多条sql语句了。
所有就啥勒??
推荐大家使用 百度、Bing、Google进行搜索👨💻
我们想到过这种问题,大概率别人也会遇上的,搜一搜,确实有答案低。
所以我们接着进入思考二吧。🏍
思考二:
还记得文章前面所说:就是希望通过一条update语句,根据不同的条件改变多条需要改变的数据。
我们直接 搜怎么一条update用不同条件修改多条数据勒
就是会搜到一个下面的这样的sql语句。
update 表名 set 列1= case when 条件1 then 值1 when 条件2 then 值2 end, 列2= case when 条件1 then 值1 when 条件2 then 值2 end, where 条件
说实话,看到这条语句的那一刻,感觉自己又没有学过mysql了,连crud工程师都算不上(捂脸)。
解释:
我们要 修改列1, 当when 条件1 满足时,则将 列1 修改为 then 后面跟着的 值1,when 条件2 满足,则将列1修改为then 后面跟着的值2。
这样一样,我们就可以执行多条语句了啊。
2.实现
我们将之前的mapper层的接口传入的参数做一下更改。
int patchByDocumentId(@Param("documentId") Long documentId,@Param("answers") List<UpdateDocumentAnswer> answers);
mapper.xml的实现如下:
<update id="patchByDocumentId"> update document_answer <set> <trim prefix="template_question_id = case" suffix="end,"> <foreach collection="answers" item="answer"> <if test="answer.templateQuestionId != null"> when id=#{answer.id} then #{answer.templateQuestionId} </if> </foreach> </trim> <trim prefix="answer = case" suffix="end,"> <foreach collection="answers" item="answer"> <if test="answer.answer != null"> when id=#{answer.id} then #{answer.answer} </if> </foreach> </trim> <trim prefix="comments = case" suffix="end,"> <foreach collection="answers" item="answer"> <if test="answer.comments != null"> when id=#{answer.id} then #{answer.comments} </if> </foreach> </trim> </set> <where> document_id=#{documentId} <if test="answers != null"> and id in <foreach collection="answers" separator="," item="answer" open="(" close=")"> #{answer.id} </foreach> </if> </where> </update>
生成的sql日志
update document_answer SET template_question_id = case when id=? then ? when id=? then ? end, answer = case when id=? then ? when id=? then ? end, comments = case when id=? then ? when id=? then ? end WHERE document_id=? and id in ( ? , ? )
换上我们想要的值:
update document_answer SET template_question_id = case when id=1 then 2 when id=1 then 3 end, answer = case when id=1 then '内容1' when id=2 then '内容2' end, comments = case when id=1 then '评论1' when id=2 then '评论2' end WHERE document_id=2 and id in ( 1 , 2 )
执行规则: 上面这种方式,更新的记录的数量取决于list集合的数量,且每条记录中的值和对应记录的ID是一一对应的。
结束了,周日更文一篇。
后语
更惭愧的是,我还没有学会。我们一起加油吧
希望本篇文章能让你感到有所收获!!!
祝
我们:待别日相见时,都已有所成
。欢迎大家一起讨论问题😁,躺了🛌