MybatisPlus真正的批量新增

文章目录


前言

在Mybatis-Plus的 IService接口中,默认提供 saveBatch批量插入,也是唯一一个默认批量插入。

java 复制代码
public interface IService<T> {
    ...

    @Transactional(
        rollbackFor = {Exception.class}
    )
    default boolean saveBatch(Collection<T> entityList) {
        return this.saveBatch(entityList, 1000);
    }
    ...
}

在数据量不是很大的情况下可以直接使用,但是saveBatch底层实现是一条一条执行的,插入多少条数据就相当于执行了多少次的插入sql。

saveBatch内部实现代码

com.baomidou.mybatisplus.extension.service.impl.ServiceImpl#saveBatch

java 复制代码
    @Transactional(
        rollbackFor = {Exception.class}
    )
    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);
        });
    }

为了实现真正高效的批量插入,以下使用 insertBatchSomeColumn 方法,实现一次性批量插入。

pom.xml

xml 复制代码
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3</version>
        </dependency>

application.yml

yml 复制代码
server:
  port: 8080
  servlet:
    context-path: /
spring:
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
     url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC&rewriteBatchedStatements=true
     username: root
     password: 123456
     driver-class-name: com.mysql.cj.jdbc.Driver

logging:
  level:
    root: info
mybatis-plus:
  # 如果是放在resource目录 classpath:/mapper/*Mapper.xml
  mapper-locations: classpath:/mapper/*Mapper.xml,/mapper/**/*Mapper.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.qf.**
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

配置类

java 复制代码
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 InsertBatchInjector 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;
    }
}
java 复制代码
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {
    @Bean
    public InsertBatchInjector sqlInjector() {
        return new InsertBatchInjector();
    }
}

实体类

java 复制代码
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author qixiansheng
 * @version 1.0
 * @data 2025/12/18 21:31
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class Orders implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    private Date createTime;

    private BigDecimal price;

    private Integer status;
}

Mapper

java 复制代码
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.util.List;

public interface BatchMapper<T> extends BaseMapper<T> {
    /**
     * 真正的批量插入
     * @param entityList
     */
    Integer insertBatchSomeColumn(List<T> entityList);
}
java 复制代码
import com.qf.entity.Orders;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author qixiansheng
 * @version 1.0
 * @data 2025/12/18 21:33
 */
@Mapper
public interface OrderMapper extends BatchMapper<Orders> {

}

Controller

java 复制代码
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.entity.DeviceRecord;
import com.qf.entity.Orders;
import com.qf.mapper.OrderMapper;
import com.qf.service.IDeviceRecordService;
import com.qf.service.IOrdersService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author qf
 * @since 2025-06-12
 */
@RestController
@RequestMapping("/test")
public class TestController {
    @Autowired
    private OrderMapper orderMapper;

    @GetMapping("save")
    public Integer save() {
        Date date = DateUtil.parse("2025-08-01 21:00:00");

        List<Orders> orders = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            Date offset = DateUtil.offsetMonth(date, i);
            Orders order = new Orders();
            order.setId(IdUtil.getSnowflake(1, 1).nextId());
            order.setCreateTime(offset);
            order.setPrice(new BigDecimal(i));
            order.setStatus(1);
            orders.add(order);
        }
        return orderMapper.insertBatchSomeColumn(orders);
    }
}

相关推荐
Sam_Deep_Thinking8 小时前
Spring Boot 的启动原理是什么?
java·spring boot·后端
屋外雨大,惊蛰出没9 小时前
深入浅出Spring Boot
java·spring boot·ioc·aop
协享科技10 小时前
Spring Boot 与 Go 双服务架构实践:从单体拆分到通信设计
java·人工智能·spring boot·后端·架构·golang·ai编程
小林敲代码778811 小时前
记录一下IDEA中很多变量变色的方案
java·开发语言·spring boot·idea
Flittly11 小时前
【AgentScope Java新手村系列】(3)工具系统
java·spring boot·spring
Flittly12 小时前
【AgentScope Java新手村系列】(2)第一个Agent-基础对话
java·spring boot·spring·ai
小二·13 小时前
Spring Boot 3 + Vue 3 全栈开发实战
vue.js·spring boot·后端
码农飞哥13 小时前
Spring Boot 多角色权限隔离实战:接口层+路由层+UI层三层防御,杜绝生产数据泄露
spring boot·状态模式·架构设计·系统设计·权限控制
SuperArc199913 小时前
SpringBoot+Slf4j+Log4j2+mybatis 日志整合
spring boot·mybatis·log4j2·slf4j·日志整合
lfwh14 小时前
探针程序技术解析:基于 Spring Boot 非 Web 模式的云服务监控告警系统
前端·spring boot·后端