注:基于mysql数据库进行测试,而且自增主键是否支持未测试,详见mybatis-plus框架 InsertBatchSomeColumn源码注释
mybatis-plus默认的批量插入(saveBatch方法)是多个insert into for循环进行执行,每次执行都是一个insert into语句,效率极低。
insert into user(id,age) values(1,20);
insert into user(id,age) values(2,25);
并不是insert into user(id,age) values(1,20),(2,25);
mybatis-plus本身是支持高效批量添加的【InsertBatchSomeColumn】
此类中的无参构造:
public InsertBatchSomeColumn() {
super("insertBatchSomeColumn");
}
调用父类构造方法时,会传入指定的一个方法名。所以想用这个批量添加时,在mapper层我们自定义的方法名必须是“insertBatchSomeColumn”,与其保持一致,否则会报错。
@Mapper
public interface UserMapper extends BaseMapper<User> {
Integer insertBatchSomeColumn(List<User> users);
}
自定义sql注入器继承默认的注入器,获取到父类的所有增删改查方法,然后将InsertBatchSomeColumn添加到方法集合中,最后将自定义sql注入器注册到spring容器中。
@Configuration
public class InsertBatchSqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
methodList.add(new InsertBatchSomeColumn());
return methodList;
}
}
InsertBatchSomeColumn#injectMappedStatement方法中,根据批量添加操作的方法(insertBatchSomeColumn)将实体等信息,拼接为<foreach>标签进行批量添加操作
<insert id='insertBatchSomeColumn'>
insert into user(id,age)
<foreach collection='list' item='et' separator=','>
values(#{et.id},#{et.age)
</foreach>
</insert>
service调用进行批处理操作
@Service
public class UserService extends ServiceImpl<UserMapper, User> {
public Integer batchSave(List<User> users) {
if (CollectionUtils.isEmpty(users)) {
return 0;
}
return this.baseMapper.insertBatchSomeColumn(users);
}
}