要实现批量更新,首先得设置mysql支持批量操作,在jdbc链接中需要附加
&allowMultiQueries=true
属性才行
例如:
jdbc:mysql://localhost:3306/dbname?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
UPDATE course SET name = 'course1' WHERE id = 'id1';
UPDATE course SET name = 'course1' WHERE id in ('id1', 'id2', 'id3);
<update id="updateBatch" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update course
<set>
name=${item.name}
set>
where id = ${item.id}
foreach>
update>
一条记录update一次,性能比较差,容易造成阻塞。
case when
语法来实现这个功能。UPDATE course
SET name = CASE id
WHEN 1 THEN 'name1'
WHEN 2 THEN 'name2'
WHEN 3 THEN 'name3'
END,
title = CASE id
WHEN 1 THEN 'New Title 1'
WHEN 2 THEN 'New Title 2'
WHEN 3 THEN 'New Title 3'
END
WHERE id IN (1,2,3)
这条sql的意思是,如果id为1,则name的值为name1,title的值为New Title1;依此类推。
在Mybatis中的配置则如下:
<update id="updateBatch" parameterType="list">
update course
<trim prefix="set" suffixOverrides=",">
<trim prefix="peopleId =case" suffix="end,">
<foreach collection="list" item="i" index="index">
<if test="i.peopleId!=null">
when id=#{i.id} then #{i.peopleId}
if>
foreach>
trim>
<trim prefix=" roadgridid =case" suffix="end,">
<foreach collection="list" item="i" index="index">
<if test="i.roadgridid!=null">
when id=#{i.id} then #{i.roadgridid}
if>
foreach>
trim>
<trim prefix="type =case" suffix="end," >
<foreach collection="list" item="i" index="index">
<if test="i.type!=null">
when id=#{i.id} then #{i.type}
if>
foreach>
trim>
<trim prefix="unitsid =case" suffix="end," >
<foreach collection="list" item="i" index="index">
<if test="i.unitsid!=null">
when id=#{i.id} then #{i.unitsid}
if>
foreach>
trim>
trim>
where
<foreach collection="list" separator="or" item="i" index="index" >
id=#{i.id}
foreach>
update>
上面是使用xml配置文件进行的批量修改,另外,更详细的介绍可以参考这位老哥哥的博客
下面看使用注解如何写批量更新操作:
首先定义批量更新的接口,参数使用@Param
注解界定;
public interface WarningMapper {
@UpdateProvider(method = "updateBatch", type = WarningProvider.class)
int updateBatch(@Param(value = "list") List records);
}
提供provider:
class WarningProvider {
public String updateBatch(final Map> map) {
List records = map.get("list");//注意这里参数是map获取list
StringBuilder sb = new StringBuilder();
sb.append("update " + TABLE_NAME);
sb.append(" set now_value = case appid");//这里可以仿照set now_value 设置其他值的修改
MessageFormat mfNowValue = new MessageFormat("#'{'list[{0}].now_value'}'");
for (int i = 0; i < records.size(); i++) {
sb.append(" when ");
sb.append(records.get(i).getAppid());
sb.append(" then ");
sb.append(mfNowValue.format(new Object[] { i }));
}
sb.append(" end ");
sb.append("where appid in");
sb.append("(");
for (int size = 0; size < records.size(); size++) {
sb.append(records.get(size).getAppid());
if (size < records.size() - 1) {
sb.append(",");
}
}
sb.append(")");
return sb.toString();
}
}
上面主要注意表达式"#'{'list[{0}].now_value'}'"
的使用
批量插入操作也可以参考批量更新,比较简单不需要case语句
这里在介绍一下Mybatis的常用注解
@Options常用属性:
DEFAULT
,TRUE
,FALSE
三种值,默认DEFAULT
表示刷新查询语句的缓存 举例:一个插入数据操作的mapper定义如下:
public interface WarningMapper {
@Insert(value = "insert into dtjx_warning"
+ " (trans_id,monitor_type,creator,created,filter,version)"
+ " values (#{trans_id},#{monitor_type},#{creator},#{created},#{filter},version+1)")
@Options(keyProperty = "appid", useGeneratedKeys = true, keyColumn = "appid") // 用options属性的useGenerateKeys可以返回自动增长的主键信息
int insert(WarningModel record);
}
更多注解使用方法,请参考官方文档