批量更新:
一条sql
语句来批量更新所有数据,下面直接看一下在mybatis
中通常是怎么写的(去掉mybatis
语法就是原生的sql
语句了,所有就没单独说sql
是怎么写的)
<update id="updateBatch" parameterType="java.util.List">
update mydata_table
set status=
<foreach collection="list" item="item" index="index"
separator=" " open="case ID" close="end">
when #{item.id} then #{item.status}
</foreach>
where id in
<foreach collection="list" index="index" item="item"
separator="," open="(" close=")">
#{item.id,jdbcType=BIGINT}
</foreach>
</update>
其中when...then...
是sql
中的"switch"
语法。这里借助mybatis
的<foreach>
语法来拼凑成了批量更新的sql
,上面的意思就是批量更新id
在updateBatch
参数所传递List
中的数据的status
字段。还可以使用<trim>
实现同样的功能,代码如下:
<update id="updateBatch" parameterType="java.util.List">
update mydata_table
<trim prefix="set" suffixOverrides=",">
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
when id=#{item.id} then #{item.status}
</foreach>
</trim>
</trim>
where id in
<foreach collection="list" index="index" item="item" separator="," open="(" close=")">
#{item.id,jdbcType=BIGINT}
</foreach>
</update>
<trim>
属性说明
1.prefix,suffix
表示在trim
标签包裹的部分的前面或者后面添加内容
2.如果同时有prefixOverrides,suffixOverrides
表示会用prefix,suffix
覆盖Overrides
中的内容。
3.如果只有prefixOverrides,suffixOverrides
表示删除开头的或结尾的xxxOverides
指定的内容。
上述代码转化成sql
如下:
update mydata_table
set status =
case
when id = #{item.id} then #{item.status}//此处应该是<foreach>展开值
...
end
where id in (...);
当然这是最简单的批量更新实现,有时候可能需要更新多个字段,那就需要将
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
when id=#{item.id} then #{item.status}
</foreach>
</trim>
复制拷贝多次,更改prefix
和when...then...
的内容即可.而如果当需要为某个字段设置默认值的时候可以使用else
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
when id=#{item.id} then #{item.status}
</foreach>
else default_value
</trim>
还有更常见的情况就是需要对要更新的数据进行判断,只有符合条件的数据才能进行更新,这种情况可以这么做:
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
<if test="item.status !=null">
when id=#{item.id} then #{item.status}
</if>
</foreach>
</trim>
这样的话只有要更新的list
中status != null && status != -1
的数据才能进行status
更新.其他的将使用默认值更新,而不会保持原数据不变.如果要保持原数据不变呢?即满足条件的更新,不满足条件的保持原数据不变,简单的来做就是再加一个<if>
,因为mybatis
中没有if...else...
语法,但可以通过多个<if>
实现同样的效果,如下:
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
<if test="item.status !=null ">
when id=#{item.id} then #{item.status}
</if>
<if test="item.status == null ">
when id=#{item.id} then mydata_table.status //这里就是原数据
</if>
</foreach>
</trim>
整体批量更新的写法如下:
<update id="updateBatch" parameterType="java.util.List">
update mydata_table
<trim prefix="set" suffixOverrides=",">
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
<if test="item.status !=null ">
when id=#{item.id} then #{item.status}
</if>
<if test="item.status == null ">
when id=#{item.id} then mydata_table.status//原数据
</if>
</foreach>
</trim>
</trim>
where id in
<foreach collection="list" index="index" item="item" separator="," open="(" close=")">
#{item.id,jdbcType=BIGINT}
</foreach>
</update>
批量新增
<insert id="insertByBatch" parameterType="java.util.List"> insert into attachment_table (name, logID,url) values <foreach collection="list" item="item" index="index" separator=","> (#{item.name,jdbcType=VARCHAR}, #{item.logid,jdbcType=INTEGER},#{item.url,jdbcType=LONGVARCHAR}) </foreach> </insert>
批量删除
<delete id="deleteMoreEmp" parameterType="int[]">
delete from emp where empno in
<foreach collection="array" item="arr" index="no" open="("
separator="," close=")">
#{arr}
</foreach>
</delete>
属性 | 描述 |
item | 循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details。 具体说明:在list和数组中是其中的对象,在map中是value。 该参数为必选。 |
collection | 要做foreach的对象,作为入参时,List<?>对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键。 |
separator | 元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。 |
open | foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选。 |
close | foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。 |
index | 在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。 |