Skip to content

Commit

Permalink
批量更新批次数据提交切割处理 (#6086)
Browse files Browse the repository at this point in the history
  • Loading branch information
VampireAchao committed Apr 24, 2024
1 parent 8922528 commit 661341f
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import org.apache.ibatis.executor.BatchResult;
Expand Down Expand Up @@ -61,9 +62,18 @@ public class MybatisBatch<T> {

private final Collection<T> dataList;

private final int batchSize;

public MybatisBatch(SqlSessionFactory sqlSessionFactory, Collection<T> dataList) {
this.sqlSessionFactory = sqlSessionFactory;
this.dataList = dataList;
this.batchSize = Constants.DEFAULT_BATCH_SIZE;
}

public MybatisBatch(SqlSessionFactory sqlSessionFactory, Collection<T> dataList, int batchSize) {
this.sqlSessionFactory = sqlSessionFactory;
this.dataList = dataList;
this.batchSize = batchSize;
}

/**
Expand Down Expand Up @@ -129,13 +139,17 @@ public List<BatchResult> execute(boolean autoCommit, BatchMethod<T> batchMethod)
* @return 批处理结果
*/
public List<BatchResult> execute(boolean autoCommit, String statement, ParameterConvert<T> parameterConvert) {
List<BatchResult> resultList = new ArrayList<>(dataList.size());
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, autoCommit)) {
for (T data : dataList) {
sqlSession.update(statement, toParameter(parameterConvert, data));
}
List<BatchResult> resultList = sqlSession.flushStatements();
if(!autoCommit) {
sqlSession.commit();
List<List<T>> split = CollectionUtils.split(dataList, batchSize);
for (List<T> splitedList : split) {
for (T data : splitedList) {
sqlSession.update(statement, toParameter(parameterConvert, data));
}
resultList.addAll(sqlSession.flushStatements());
if (!autoCommit) {
sqlSession.commit();
}
}
return resultList;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,7 @@
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.MybatisBatchUtils;
import com.baomidou.mybatisplus.core.toolkit.MybatisUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.exceptions.TooManyResultsException;
Expand All @@ -43,6 +36,7 @@
import org.apache.ibatis.session.SqlSessionFactory;

import java.io.Serializable;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
Expand Down Expand Up @@ -461,10 +455,21 @@ default boolean saveOrUpdate(T entity) {
* @since 3.5.7
*/
default List<BatchResult> saveBatch(Collection<T> entityList) {
return saveBatch(entityList, Constants.DEFAULT_BATCH_SIZE);
}

/**
* 插入(批量)
*
* @param entityList 实体对象集合
* @param batchSize 插入批次数量
* @since 3.5.7
*/
default List<BatchResult> saveBatch(Collection<T> entityList, int batchSize) {
MybatisMapperProxy<?> mybatisMapperProxy = MybatisUtils.getMybatisMapperProxy(this);
MybatisBatch.Method<T> method = new MybatisBatch.Method<>(mybatisMapperProxy.getMapperInterface());
SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSessionFactory(mybatisMapperProxy);
return MybatisBatchUtils.execute(sqlSessionFactory, entityList, method.insert());
return MybatisBatchUtils.execute(sqlSessionFactory, entityList, method.insert(), batchSize);
}

/**
Expand All @@ -474,10 +479,21 @@ default List<BatchResult> saveBatch(Collection<T> entityList) {
* @since 3.5.7
*/
default List<BatchResult> updateBatchById(Collection<T> entityList) {
return updateBatchById(entityList, Constants.DEFAULT_BATCH_SIZE);
}

/**
* 根据ID 批量更新
*
* @param entityList 实体对象集合
* @param batchSize 插入批次数量
* @since 3.5.7
*/
default List<BatchResult> updateBatchById(Collection<T> entityList, int batchSize) {
MybatisMapperProxy<?> mybatisMapperProxy = MybatisUtils.getMybatisMapperProxy(this);
MybatisBatch.Method<T> method = new MybatisBatch.Method<>(mybatisMapperProxy.getMapperInterface());
SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSessionFactory(mybatisMapperProxy);
return MybatisBatchUtils.execute(sqlSessionFactory, entityList, method.updateById());
return MybatisBatchUtils.execute(sqlSessionFactory, entityList, method.updateById(), batchSize);
}

/**
Expand All @@ -487,6 +503,17 @@ default List<BatchResult> updateBatchById(Collection<T> entityList) {
* @since 3.5.7
*/
default List<BatchResult> saveOrUpdateBatch(Collection<T> entityList) {
return saveOrUpdateBatch(entityList, Constants.DEFAULT_BATCH_SIZE);
}

/**
* 批量修改或插入
*
* @param entityList 实体对象集合
* @param batchSize 插入批次数量
* @since 3.5.7
*/
default List<BatchResult> saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
MybatisMapperProxy<?> mybatisMapperProxy = MybatisUtils.getMybatisMapperProxy(this);
Class<?> entityClass = GenericTypeUtils.resolveTypeArguments(getClass(), BaseMapper.class)[0];
TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
Expand All @@ -495,7 +522,7 @@ default List<BatchResult> saveOrUpdateBatch(Collection<T> entityList) {
return saveOrUpdateBatch(entityList, (sqlSession, entity) -> {
Object idVal = tableInfo.getPropertyValue(entity, keyProperty);
return StringUtils.checkValNull(idVal) || CollectionUtils.isEmpty(sqlSession.selectList(statement, entity));
});
}, batchSize);
}

/**
Expand All @@ -505,10 +532,21 @@ default List<BatchResult> saveOrUpdateBatch(Collection<T> entityList) {
* @since 3.5.7
*/
default List<BatchResult> saveOrUpdateBatch(Collection<T> entityList, BiPredicate<BatchSqlSession, T> insertPredicate) {
return saveOrUpdateBatch(entityList, insertPredicate, Constants.DEFAULT_BATCH_SIZE);
}

/**
* 批量修改或插入
*
* @param entityList 实体对象集合
* @param batchSize 插入批次数量
* @since 3.5.7
*/
default List<BatchResult> saveOrUpdateBatch(Collection<T> entityList, BiPredicate<BatchSqlSession, T> insertPredicate, int batchSize) {
MybatisMapperProxy<?> mybatisMapperProxy = MybatisUtils.getMybatisMapperProxy(this);
MybatisBatch.Method<T> method = new MybatisBatch.Method<>(mybatisMapperProxy.getMapperInterface());
SqlSessionFactory sqlSessionFactory = MybatisUtils.getSqlSessionFactory(mybatisMapperProxy);
return MybatisBatchUtils.saveOrUpdate(sqlSessionFactory, entityList, method.insert(), insertPredicate, method.updateById());
return MybatisBatchUtils.saveOrUpdate(sqlSessionFactory, entityList, method.insert(), insertPredicate, method.updateById(), batchSize);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
* Collection工具类
Expand Down Expand Up @@ -232,4 +235,27 @@ public static <T> List<T> toList(T... t) {
return Collections.emptyList();
}

/**
* 切割集合为多个集合
* @param entityList 数据集合
* @param batchSize 每批集合的大小
* @return 切割后的多个集合
* @param <T> 数据类型
*/
public static <T> List<List<T>> split(Collection<T> entityList, int batchSize) {
if (isEmpty(entityList)) {
return Collections.emptyList();
}
Assert.isFalse(batchSize < 1, "batchSize must not be less than one");
final Iterator<T> iterator = entityList.iterator();
final List<List<T>> results = new ArrayList<>(entityList.size() / batchSize);
while (iterator.hasNext()) {
final List<T> list = IntStream.range(0, batchSize).filter(x -> iterator.hasNext())
.mapToObj(i -> iterator.next()).collect(Collectors.toList());
if (!list.isEmpty()) {
results.add(list);
}
}
return results;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,10 @@ public interface Constants extends StringPool, Serializable {
*/
String WRAPPER_PARAM = "MPGENVAL";
String WRAPPER_PARAM_MIDDLE = ".paramNameValuePairs" + DOT;


/**
* 默认批次提交数量
*/
int DEFAULT_BATCH_SIZE = 1000;
}
Loading

0 comments on commit 661341f

Please sign in to comment.