“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 24 天,点击查看活动详情”
引言
mybatis-plus内置的批量插入方法saveBatch
并不是真正的批量写入,而是通过executeBatch分批提交。
boolean saveBatch(Collection<T> entityList, int batchSize);
所以想提升批量插入的性能可以采用多值插入。
多值插入的方式1: JDBC URL批量处理参数配置, 在mysql连接信息中添加rewriteBatchedStatements=true使得执行效率大幅提升。
多值插入的方式2: 通过sql注入器注入InsertBatchSomeColumn方法实现了insert的多值插入,提升了批量插入的性能。
I JDBC URL批量处理参数配置【推荐】
useServerPrepStmts = false& rewriteBatchedStatements = true
- useServerPrepStmts 参数影响数据精度
- 配置rewriteBatchedStatements=true,在调用 executeBatch() 批量执行 INSERT语句时,mysql内部会自动将批量提交的sql重写为insert多值插入再执行。
批量sql重写开关参数rewriteBatchedStatements默认是关闭的,mysql连接驱动器版本3.1.13以后支持该配置
II 重写saveBatch实现多值插入
通过sql注入器注入InsertBatchSomeColumn方法实现了insert的多值插入,提升了批量插入的性能。
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Resource
private UserMapper userMapper;
/**
*
* @param entityList
* @param batchSize
* @return
*/
@Override
@Transactional(rollbackFor = {Exception.class})
public boolean saveBatch(Collection<User> entityList, int batchSize) {
try {
int size = entityList.size();
int idxLimit = Math.min(batchSize, size);
int i = 1;
//保存单批提交的数据集合
List<User> oneBatchList = new ArrayList<>();
for(Iterator<User> var7 = entityList.iterator(); var7.hasNext(); ++i) {
User element = var7.next();
oneBatchList.add(element);
if (i == idxLimit) {
userMapper.insertBatchSomeColumn(oneBatchList);
//每次提交后需要清空集合数据
oneBatchList.clear();
idxLimit = Math.min(idxLimit + batchSize, size);
}
}
}catch (Exception e){
log.error("saveBatch fail",e);
return false;
}
return true;
}
}