首先,mybatis框架就是对sql语句进行了封装,用xml的方式,通过标签和属性解析执行sql语句,我们知道,在表中插入记录的sql语句为:
INSERT INTO 表名称 (列1, 列2,…) VALUES (值1, 值2,…)
在插入过程中,数据库会默认加上事务,也就是说批量插入是具有原子性的。有批量插入,但却没有支持批量更新的sql语句,仅有对一条满足条件的记录进行更新:
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
在mysql
中,我们可以用replace into
关键字达到批量更新的效果,其原理是删除原有的一条记录(如有), 并且插入一条新的记录来替换原记录,其常用语法如下:
REPLACE INTO 表名称 (列1, 列2,…) VALUES (值1,值2),(值3,值4),…(值x,值y)
需要注意的是,插入数据的表必须有主键或者是唯一索引,不然replace into
会直接插入数据,这将导致表中出现重复的数据,这很好理解,因为其本质上是insert into
的“升级”。
知道了更新语句后,在mybatis中便有了两种简单方便的批量更新方法:
第一种:
xxxMapper.java
public interface xxxMapper {
int updateBatch(@Param("list") List<yourClass> yourListName);
}
xxxMapping.xml
<update id="updateBatch" parameterType="java.util.List" >
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update 表名
<set >
<if test="item.字段1 != null" >
字段1 = #{item.字段1,jdbcType=INTEGER},
</if>
<if test="item.stepid != null" >
字段2 = #{item.字段2,jdbcType=VARCHAR},
</if>
......
</set>
where id = #{item.id,jdbcType=INTEGER}
</foreach>
</update>
第一种是用mybatis提供的foreach
标签,循环执行update语句实现批量更新,在foreach标签中有几个属性,
item,index,collection,open,separator,close
在更新操作中,我们只需要关注collection
属性和item
属性即可,我们看一段mybatis源码:
private Object wrapCollection(Object object) {
DefaultSqlSession.StrictMap map;
// 如果传入参数是一个集合
if (object instanceof Collection) {
//创建1个Map
map = new DefaultSqlSession.StrictMap();
map.put("collection", object);
//注意 如果参数是list
if (object instanceof List) {
//那么传来的参数,collection的默认写法collection="list"
map.put("list", object);
}
return map;
} else if (object != null && object.getClass().isArray()) {
map = new DefaultSqlSession.StrictMap();
//数组的默认写法为collection="array"
map.put("array", object);
return map;
} else {
return object;
}
}
可以看出,当传入参数是集合时,collection的默认值是list,当传入参数是数组时,collection的默认值的array,如果是多个参数,那么就要封装一个key是参数名,value是参数对象的map了。所以,这里collection就用默认值list,在mapper中,用@param("list")
注解传入参数即可。
item属性表示传入集合中每一个元素进行迭代时的别名,相当于sql中的别名。
需要注意的是,别忘了用别名 . 属性!否则会抛找不到字段异常!
第二种:
<insert id="updateBatch" useGeneratedKeys="true" keyProperty="id" parameterType="java.util.List" >
replace into 表名
(id,字段2,字段3,字段4,...,字段N)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.id}, #{item.字段2},#{item.字段3},#{item.字段4},...,#{item.字段N})
</foreach>
</insert>
由于replace into是先删除再插入,相当于更新。因此需要注意表需有主键,且是自增的,否则将会直接批量插入,形成重复记录。
创作不易,如果有对你有帮助,点个赞呗~