本文内容包括:JDK8新特性,Spring框架,JDBC步骤
背景
公司持久层框架选型选择了Mybatis-plus(以下简称MP),框架的优劣势就不在这里展开说了。主要来谈谈在工作上遇到的事情。
在一次调试中发现,使用批量新增功能在console打印的是每一条数据一条insert,这个对性能来说并不友好(每一条语句都会与数据库建立连接-执行sql-结束连接,具体可以看JDBC)。
批量新增接口在com.baomidou.mybatisplus.extension.service#saveBatch,具体代码如下:
com.baomidou.mybatisplus.extension.toolkit#executeBatch
public static <E> boolean executeBatch(Class<?> entityClass, Log log, Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
Assert.isFalse(batchSize < 1, "batchSize must not be less than one", new Object[0]);
return !CollectionUtils.isEmpty(list) && executeBatch(entityClass, log, (sqlSession) -> {
int size = list.size();
int i = 1;
for(Iterator var6 = list.iterator(); var6.hasNext(); ++i) {
E element = var6.next();
consumer.accept(sqlSession, element);
if (i % batchSize == 0 || i == size) {
sqlSession.flushStatements();
}
}
});
}
在这里有个执行consumer(详细看JDK8新增接口):
com.baomidou.mybatisplus.extension.service.impl#saveBatch
public boolean saveBatch(Collection<T> entityList, int batchSize) {
String sqlStatement = this.getSqlStatement(SqlMethod.INSERT_ONE);
return this.executeBatch(entityList, batchSize, (sqlSession, entity) -> {
sqlSession.insert(sqlStatement, entity);
});
}
可以看出是不断执行insert方法。
然后就很怀疑,MP怎么可能没有发现这个问题呢?后续在官方源码找到了是有批量新增的接口com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn本着程序员盘根问底的性格去github看了下,发现了这段描述:
* <p> 不同的数据库支持度不一样!!! 只在 mysql 下测试过!!! 只在 mysql 下测试过!!! 只在 mysql 下测试过!!! </p>
* <p> 除了主键是 <strong> 数据库自增的未测试 </strong> 外理论上都可以使用!!! </p>
* <p> 如果你使用自增有报错或主键值无法回写到entity,就不要跑来问为什么了,因为我也不知道!!! </p>
估计是只支持mysql吧,看到这里的小伙伴如果用的不是mysql记得慎用。
接下来就是愉悦的接入这个接口啦!
解决方案
首先要使用接口方法是把接口加进MP然后注入到Spring
/**
* @author kwongting
* @version 1.0
* @date 2021/6/18 19:54
* @description 增加批量更新方法
*/
public class EnhancementSqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
//继承原有方法
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
//注入批量更新方法
methodList.add(new InsertBatchSomeColumn());
return methodList;
}
}
/**
* @author kwongting
* @version 1.0
* @date 2021/6/18 19:50
* @description
*/
@Configuration
@MapperScan({"com.*.*.mapper"})
public class MybatisPlusConfig {
/**
* 增强sql
* @return 增强注入
*/
@Bean
public EnhancementSqlInjector easySqlInjector() {
return new EnhancementSqlInjector();
}
}
然后再继承MP的BaseMapper添加接口达到增强。
/**
* @author kwongting
* @version 1.0
* @date 2021/6/18 20:02
* @description 增强BaseMapper
*/
public interface EnhancementBaseMapper<T> extends BaseMapper<T> {
/**
* 批量添加
* @param entityList 数据列表
* @return 成功标示
*/
Integer insertBatchSomeColumn(Collection<T> entityList);
}
接下来就可以愉悦的调用mapper里面的insertBatchSomeColumn达到批量新增啦~