美文网首页
Mybatis-plus框架原有批量新增性能问题

Mybatis-plus框架原有批量新增性能问题

作者: b77f686a8725a | 来源:发表于2021-07-21 15:29 被阅读0次

本文内容包括: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达到批量新增啦~

相关文章

网友评论

      本文标题:Mybatis-plus框架原有批量新增性能问题

      本文链接:https://www.haomeiwen.com/subject/xuoemltx.html