不要再写循环了!mybatis批量插入数据,批量更新集合list它不香吗?

首先,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是先删除再插入,相当于更新。因此需要注意表需有主键,且是自增的,否则将会直接批量插入,形成重复记录。

创作不易,如果有对你有帮助,点个赞呗~

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值