前言
就在刚刚同事突然问我mybaits的xml中批量插入,修改语句怎么写,我一下就蒙了,即使以前写过,但我有忘记了,不知道其他小伙伴是不是也有这种情况,所以我今天特意记录一下
// 批量插入
void batchInsert(@Param("logs") List<Log> logs);
// 单个插入
void insert(Log log);
// 批量修改
void batchUpdate(@Param("logs") List<Log> logs);
// 单个修改
void update(Log log);
// 批量删除
void batchDelete(@Param("ids") List<String> ids);
// 单个删除
void delete(String id);
批量插入
- 第一种效率高一些,而且mysql中执行sql语句大小默认是1M,不过可以通过修改mysql中的配置max_allowed_packet
- 特别说明一下foreach中的collection,当参数是集合List默认就是list,当是数组就是array,是Map时就是map,如果使用@param则要一一对应起来,item相当于集合中的每个对象,separator代表每个循环后之间的衔接
- 批量插入中的paramType可以省略
// 第一种是执行一条插入语句
<insert id="batchInsert">
insert into
bridge_log
(<include refid="base_sql"/>)
values
<foreach collection="logs" item="log" separator=",">
(#{log.requestno}, #{log.status}, #{log.provideraddress},
#{log.customeraddress}, #{log.apiservicename}, #{log.apiservicemethod},
#{log.requestbytesize}, #{log.responsebytesize}, #{log.biztimecost},#{log.timecost},
#{log.bizstatus}, #{log.errormessage}, #{log.createtime})
</foreach>
</insert>
// 第二种是执行多条插入语句
<insert id="batchInsert">
<foreach collection="logs" item="log" separator=";">
insert into
bridge_log
(<include refid="base_sql"/>)
values
(#{log.requestno}, #{log.status}, #{log.provideraddress},
#{log.customeraddress}, #{log.apiservicename}, #{log.apiservicemethod},
#{log.requestbytesize}, #{log.responsebytesize}, #{log.biztimecost},#{log.timecost},
#{log.bizstatus}, #{log.errormessage}, #{log.createtime})
</foreach>
</insert>
批量修改
<update id="batchUpdate">
<foreach collection="logs" separator=";" item="log">
update bridge_log
<set>
<if test="log.status != null">status =#{log.status}</if>
</set>
<where>
requestNo = #{log.requestno}
</where>
</foreach>
</update>
批量删除
推荐使用第一种
// 第一种
<delete id="batchDelete">
delete from bridge_log
<where>
requestNo in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</where>
</delete>
// 第二种
<delete id="batchDelete">
<foreach collection="ids" separator=";" item="id">
delete from bridge_log where requestNo = #{id}
</foreach>
</delete>
效果
一千条数据通过xml中批量新增大概需要378ms,而通过业务循环单个新增大概需要2037ms
总结
为什么要使用xml去批量操作,而不去通过代码业务通过for循环操作
因为要减少程序与mysql之间的io操作,虽然数据量都是一样,但通过xml批量执行只进行了mysql之间的一次连接,而通过for循环单个操作就与mysql建立多次连接。
这种的方式就可以减少durid线程池与mysql连接开销
主要就是效率比较高