Mybatis批量插入——踩坑点
最近在进行批量插入,并且返回id的时候,遇到了几个比较抽象的点,首先,是mybatis版本不对,3.3.1之后才支持批量插入返回主键,所以在主键为null的时候,先检查mybatis版本。
之后就是检查数据库中的id是否是自增的,如果不是,是否是雪花算法,当然雪花算法就不在本文中详述了。
其次,在insert返回主键的时候,使用
useGeneratedKeys="true" keyProperty="id
而不是
<insert id="batchInsert" useGeneratedKeys="true" keyColumn="id">
然后就是在批量插入的时候,进行sql语句动态拼接的时候,尽量不要使用
insert into xxx (id,permission_id, type, expression, is_del)
values
<foreach collection="list" item="rule" index="index" separator="," open="(" close=")">
#{rule.id,jdbcType=BIGINT}, #{rule.permissionId,jdbcType=BIGINT}, #{rule.type,jdbcType=INTEGER},
#{rule.expression,jdbcType=INTEGER},#{rule.isDel,jdbcType=INTEGER}
</foreach>
</insert>
这样会导致sql语句异常,当数据量大于1的时候,3个属性会不断拼接,从而早场colum doesn‘t match的异常描述
相反,这样做:
<insert id="batchInsert" useGeneratedKeys="true" keyProperty="id">
insert into xxx (id,permission_id, type, expression, is_del)
values
<foreach collection="list" item="rule" index="index" separator=",">
(#{rule.id,jdbcType=BIGINT}, #{rule.permissionId,jdbcType=BIGINT}, #{rule.type,jdbcType=INTEGER},
#{rule.expression,jdbcType=INTEGER},#{rule.isDel,jdbcType=INTEGER})
</foreach>
</insert>
就可以避免该异常了。
接下来就是最容易被忽略的点,在mapper中,这样定义 变量别名,必须用list
int batchInsert(@Param("list") List<xxx> records);
xml同上
而不是把变量别名改为其他的非“list”的名字
int batchInsert(@Param("records") List<xxx> records); 然后foreach中的collection也当作records
。