优化mybatisPlus批量新增,新增mapper层批量新增方法,附带代码生成vm模板。

一、主题

经发现,mybatisPlus只有Service中存在saveBatch()方法,而Mapper中不存在批量新增的方法,深入了解,发现mybatisPlus的Service中saveBatch()方法也是循环一条一条插入数据库。如果发现数据量较大,运行时间较长。所以文本针对mapper无批量新增和效率实现新增优化。

二、效果展示

这里使用600条数据在模拟mybatisPlus新增和优化之后的新增。看一下有什么区别
在这里插入图片描述
输出的结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到600条数据,mybatisPlus自带的批量新增使用时间8s,而通过修改SQL的方法只用了1秒。

三、mybatis-plus源码分析

通过效果图中可以看到批量新增本质上还是insert触发单个新增,这样无异于循环新增。
在这里插入图片描述

四、优化思路

上述mybatis-plus中源码中只是循环插入实现的批量新增,优化方式有以下几个思路。可能还有别的优化思路,欢迎评论区讨论发言。本文只实现思路1和3

  1. 把批量数据拼接成一个insert的SQL语句。
  2. 多线程任务去批量新增。
  3. 根据mybatis-plus预留的 insertBatchSomeColumn 方法。可能

五、代码优化

方法一:修改批量新增SQL

  1. 此方法手动给mapper新增一个批量新增方法,如效果展示的代码中goodsLabelValueService.saveBatchList(labelGoodsValueList2);

  2. Service中

    int saveBatchList(List<LabelGoodsValue> labelGoodsValueList);
    
  3. serviceImpl中

    	@Override
    	public int saveBatchList(List<LabelGoodsValue> labelGoodsValueList) {
    		return baseMapper.saveBatchList(labelGoodsValueList);
    	}
    
  4. Mapper.java中

    int saveBatchList(@Param("list") List<LabelGoodsValue> labelGoodsValueList);
    
  5. Mapper.xml中

    	<insert id="saveBatchList">
    		insert into label_goods_value
    		( id,label_id , label_name , goods_spu_id , goods_spu_name , sort , create_time , update_time , spu_code  ) values
    		<foreach item="item" index="index" collection="list" separator=",">
    			(#{item.id},#{item.labelId}, #{item.labelName}, #{item.goodsSpuId}, #{item.goodsSpuName}, #{item.sort}, #{item.createTime}, #{item.updateTime}, #{item.spuCode})
    		</foreach>
    	</insert>
    
  • 看到这里,这里提取Mapper.xml的方法,使代码生成的VM的自动生成(VM是mybatisPlus代码生成的模板)

    	<insert id="saveBatchList">
            insert into $tableName
            (#foreach($column in $columns) ${column.columnName} #if($foreach.count != $columns.size()),#end#end) values
            <foreach item="item" index="index" collection="list" separator=",">
                (#foreach($column in $columns) #{item.${column.lowerAttrName}}#if($foreach.count != $columns.size()),#end#end)
            </foreach>
        </insert>
    

方法二:使用insertBatchSomeColumn 方法

  1. 新建 Sql 注射器 BatchSqlInjector

    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.core.injector.AbstractMethod;
    import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
    import com.baomidou.mybatisplus.core.metadata.TableInfo;
    import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
    import java.util.List;
    
    public class BatchSqlInjector extends DefaultSqlInjector {
    
        @Override
        public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
            List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
            methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
            return methodList;
        }
    
    }
    
    
  2. MybatisPlusConfig 配置 BatchSqlInjector Bean

    import com.baomidou.mybatisplus.annotation.DbType;
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    @EnableTransactionManagement
    @Configuration
    public class MybatisPlusConfig {
        /**
         * 批量插入
         *
         * @return
         */
        @Bean
        public BatchSqlInjector easySqlInjector() {
            return new BatchSqlInjector();
        }
    }
    
    
    
  3. 配置 BatchBaseMapper 继承 BaseMapper

    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import java.util.Collection;
    
    public interface BatchBaseMapper<T> extends BaseMapper<T> {
        /**
         * 批量插入 仅适用于mysql
         *
         * @param entityList 实体列表
         * @return 影响行数
         */
        Integer insertBatchSomeColumn(Collection<T> entityList);
    }
    
    
  4. 业务 Mapper 继承 BatchBaseMapper

    @Repository
    public interface ISapCustomerMapper extends BatchBaseMapper<SapCustomerPO> {
    
    }
    
    
  5. service 创建 createBatch 作为新的批量插入方法

    public class SapCustomerServiceImpl extends ServiceImpl<ISapCustomerMapper, SapCustomerPO> {
    
        void createBatch(List<SapCustomerPO> entityList) {
            if(!entityList.isEmpty()){
                baseMapper.insertBatchSomeColumn(entityList);
            }
        }
    }
    
  6. 注意事项:

    1. 在使用 MyBatis-Plus 进行批量新增指定字段时,需要注意以下几点:
    2. 每次新增的数据量不要过大,建议每批次新增的数据量控制在 1000 条以内。
    3. 要新增的指定字段不能为 null,需要手动设置默认值。
    4. 如果要新增的指定字段在实体类中有对应的字段值,会被忽略。
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XuDream

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值