MyBatis foreach小记—— 批量update

    经常会用到mybatis的foreach标签来做循环操作,可以做一些sql的拼装等,标签的属性如下:

  • collection 循环对象集合;
  • item 每个迭代对象的别名;
  • index 迭代索引值;
  • open 循环语句的开始内容;
  • separator 每次迭代之间的分隔符;
  • close 循环语句的结束内容;

    以mysql为例,批量操作的sql最常见就是通过in语句、批量insert语句等:

1, delete from table where key in(key1,key2,key3...);
2, update table set ... where id in(id1,id2,id3...); 
3, insert into table(column1,column2...) values (value1-1,value1-2...),(value2-2,value2-2...);

    批量操作的sql还有很多其他的,不同数据库的对应的实现可能也不太相同,但是对于mybatis来说,最终的原则就是:

    "批量操作的sql命令要是一条SQL"

    对于批量更新应该怎么做呢?,比如有如下形式的sql:    

update table set index=0 where id=100;

update table set index=1 where id=101;

    下面这种方式就会报错:

<update id="sortBatch" parameterType="java.util.List">
  <foreach item="id" collection="ids" separator=";" index="index">
    update table set index=#{index}
    where id = #{id};
  </foreach>
</update>

   多个uodate语句用分号“;”分割开,这样是不行的,要变成一个sql,如下:

<update id="sortBatch" parameterType="java.util.List">
  update table set index=
  <foreach collection="ids" item="id" index="index" separator=" " open="case ID" close="end">
    when #{id} then #{index}
  </foreach>
  where ID in
  <foreach collection="ids" index="index" item="id" separator="," open="(" close=")">
    #{id}
  </foreach>
</update>

转换为in语句,同时对set值与id进行映射绑定(这个用到了mysql的case when then语句,其他数据库也有类似的语法),相当于把上边的两条sql变成了如下的sql:

update table set index = case ID when 100 then 0 when 101 then 1 end

where ID in (100,101);
类似的多sql批量用mybatis来做的话都可参考这种方式。





版权声明:本文为mingjia1987原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。