Mybatis Plus 默认提供了一个批量保存数据到数据库的方法,也就是 IService#saveBatch() 接口方法,其实质是遍历然后逐个insert ,如果插入数据过多会影响性能,下图为使用此方法执行1万条时间 59秒
时间上的确是太久了,然后参考网上一些优秀的人写的文章,调整优化到了2秒左右
下面是参考代码:
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public interface BaseSqlMapper<T> extends BaseMapper<T> {
/**
* 默认批次提交数量
*/
int DEFAULT_BATCH_SIZE = 1000;
/**
* 以下定义的 4个 default method, copy from {@link com.baomidou.mybatisplus.extension.toolkit.ChainWrappers}
*/
default QueryChainWrapper<T> queryChain() {
return new QueryChainWrapper<>(this);
}
default LambdaQueryChainWrapper<T> lambdaQueryChain() {
return new LambdaQueryChainWrapper<>(this);
}
default UpdateChainWrapper<T> updateChain() {
return new UpdateChainWrapper<>(this);
}
default LambdaUpdateChainWrapper<T> lambdaUpdateChain() {
return new LambdaUpdateChainWrapper<>(this);
}
/**
* 批量新增数据,自选字段 insert. 自动按每批1000插入数据库
* 此填充不会填充 FieldFill.UPDATE 的字段。
* 注意数据库默认更新的字段也需要手工设置
*
* @see MySqlInjector#getMethodList(Class)
* @param entityList 数据
* @return 插入条数
*/
@Transactional(rollbackFor = Exception.class)
default int insertBatch(List<T> entityList) {
return this.insertBatchSomeColumn(entityList, DEFAULT_BATCH_SIZE);
}
/**
* 批量新增数据,自选字段 insert
* 不会分批插入,需要分批请调用方法insertBatch或者 insertBatchSomeColumn(List<T> entityList, int size)
* 此填充不会填充 FieldFill.UPDATE 的字段。
* 注意数据库默认更新的字段也需要手工设置
*
* @see MySqlInjector#getMethodList(Class)
* @param entityList 数据
* @return 插入条数
*/
int insertBatchSomeColumn(List<T> entityList);
/**
* 分批插入。每次插入
* @param entityList 原实体对象
* @param size 分批大小
* @return 总插入记录
*/
@Transactional(rollbackFor = Exception.class)
default int insertBatchSomeColumn(List<T> entityList, int size) {
if (CollUtil.isEmpty(entityList)) {
return 0;
}
List<List<T>> split = CollUtil.split(entityList, size);
return split.stream().mapToInt(this::insertBatchSomeColumn).sum();
}
}
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
import java.util.List;
public class MySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
// 例: 不要指定了 update 填充的字段
methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
return methodList;
}
}
import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.parsers.DynamicTableNameParser;
import com.baomidou.mybatisplus.extension.parsers.ITableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.hieasy.comm.constant.Constants;
import com.hieasy.comm.utils.security.Guard;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* MP配置
*/
@Configuration
public class MybatisplusConfig {
@Resource
private HttpServletRequest request;
/*分页插件*/
@Bean
public PaginationInterceptor paginationInterceptor(){
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setLimit(-1);
return paginationInterceptor;
}
/**
* 自定义内置选装件
*
* @return
*/
@Bean
public MySqlInjector sqlInjector() {
return new MySqlInjector();
}
}
import com.hieasy.pos.common.config.BaseSqlMapper;
import com.hieasy.pos.domain.promote.comm.CxCmKehu;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface CxCmKehuMapper extends BaseSqlMapper<CxCmKehu> {
}
protected void insertCxKehu(Integer aid, Integer cxlx, Long pid, List<CxCmKehu> kehuList){
for(CxCmKehu cxkh:kehuList){
cxkh.setAccountid(aid);
cxkh.setCxlx(cxlx);
cxkh.setPid(pid);
// cxCmKehuMapper.insert(cxkh);
}
cxCmKehuMapper.insertBatchSomeColumn(kehuList);
}