BaseMapper中为提供批量插入接口,但是在com.baomidou.mybatisplus.extension.service.IService接口中提供了saveBatch批量插入方法。
1.1入门使用 新建一个接口,继承Iservice接口,泛型为被操作的实体类 package com.wsh.service;import com.baomidou.mybatisplus.extension.service.IService;import com.wsh.entity.Order;public interface BatchInsertService extends IService {} 创建一个方法,继承ServiceImpl,并且实现上述接口BatchInsertService package com.wsh.service;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.wsh.mapper.OrderMapper;import com.wsh.entity.Order;import org.springframework.stereotype.Service;@Servicepublic class BatchInsertServiceImpl extends ServiceImpl implements BatchInsertService{}其中,extends ServiceImpl,Order是被操作的实体类,Ordermapper是继承BaseMapper的自定义接口,如下:
package com.wsh.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.wsh.entity.Order;// 使用mybatis-plus增强接口public interface OrderMapper extends BaseMapper {} 批量保存测试 package com.wsh;import com.wsh.service.BatchInsertService;import org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;import com.wsh.entity.Order;import javax.annotation.Resource;import java.util.ArrayList;import java.util.Date;@SpringBootTestpublic class TestBatchInsertService { @Resource private BatchInsertService batchInsertService; @Test public void testBatchSave(){ long start = System.currentTimeMillis(); ArrayList orders = new ArrayList(); for (int i = 0; i Preparing: INSERT INTO orders ( order_id, order_date, order_name ) VALUES ( ?, ?, ? ) ==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99951(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99952(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99953(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99954(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99955(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99956(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99957(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99958(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99959(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99960(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99961(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99962(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99963(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99964(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99965(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99966(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99967(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99968(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99969(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99970(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99971(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99972(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99973(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99974(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99975(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99976(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99977(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99978(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99979(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99980(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99981(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99982(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99983(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99984(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99985(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99986(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99987(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99988(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99989(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99990(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99991(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99992(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99993(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99994(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99995(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99996(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99997(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99998(String)==> Parameters: 0(Integer), 2023-07-28 10:16:42.773(Timestamp), wsh99999(String)保存时间为:73474true 1.2 原理方法Iservice接口中saveBatch方法:
/** * 插入(批量) * * @param entityList 实体对象集合 * @param batchSize 插入批次数量 */ boolean saveBatch(Collection entityList, int batchSize);ServiceImpl.java实现类中的saveBatch方法:
/** * 批量插入 * * @param entityList ignore * @param batchSize ignore * @return ignore */ @Transactional(rollbackFor = Exception.class) @Override public boolean saveBatch(Collection entityList, int batchSize) { String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE); try (SqlSession batchSqlSession = sqlSessionBatch()) { int i = 0; for (T anEntityList : entityList) { batchSqlSession.insert(sqlStatement, anEntityList); if (i >= 1 && i % batchSize == 0) { batchSqlSession.flushStatements(); } i++; } batchSqlSession.flushStatements(); } return true; }sqlSessionBatch:
/** * 批量操作 SqlSession */ protected SqlSession sqlSessionBatch() { return SqlHelper.sqlSessionBatch(currentModelClass()); } /** * 批量操作 SqlSession * * @param clazz 实体类 * @return SqlSession */ public static SqlSession sqlSessionBatch(Class clazz) { // TODO 暂时让能用先,但日志会显示Closing non transactional SqlSession,因为这个并没有绑定. return GlobalConfigUtils.currentSessionFactory(clazz).openSession(ExecutorType.BATCH); }注意:openSession(ExecutorType.BATCH),到这里就熟悉了。 插入十万条数据,时间为:73474
2.使用MybatisPlus自定义新增 2.1配置工作注: 仅适用于MySQL
创建自定义数据方法注入类 package com.wsh.util;import com.baomidou.mybatisplus.core.injector.AbstractMethod;import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;import com.baomidou.mybatisplus.extension.injector.methods.additional.InsertBatchSomeColumn;import java.util.List;public class EasySqlInjector extends DefaultSqlInjector { @Override public List getMethodList(Class mapperClass) { // 防止父类方法不可用 List methodList = super.getMethodList(mapperClass); methodList.add(new InsertBatchSomeColumn()); return methodList; }} 在MybatisPlus配置文件MybatisPlusConfig加入自定义 package com.wsh.config;import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;import com.wsh.util.EasySqlInjector;import org.mybatis.spring.annotation.MapperScan;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.transaction.annotation.EnableTransactionManagement;@EnableTransactionManagement@Configuration@MapperScan("com.wsh.mapper")public class MybatisPlusConfig { @Bean public EasySqlInjector easySqlInjector(){ return new EasySqlInjector(); }} 扩展通用Mapper,支持数据批量插入,即:创建EasyBaseMapper接口继承BaseMapper package com.wsh.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import java.util.Collection;/** * @author suahng * @date 2023-07-21 20:47 * @dec */public interface EasyBaseMapper extends BaseMapper { /** * 批量插入,仅使用批量插入 * @param entityList 实体列表 * @return 影响行数 */ Integer insertBatchSomeColumn(Collection entityList);} 定义业务mapper接口,继承刚刚扩展的EasyBaseMapper package com.wsh.mapper;import com.wsh.entity.Order;import org.springframework.stereotype.Repository;@Repositorypublic interface EasyMapper extends EasyBaseMapper {} 定义Service接口 package com.wsh.service;import com.baomidou.mybatisplus.extension.service.IService;import com.wsh.entity.Order;import java.util.Collection;public interface EasyService extends IService { /** * 批量插入,仅适用于 mysql * @param orderList * @return */ public Integer BatchSave(Collection orderList);} 定义service接口的实现类 package com.wsh.service;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.wsh.mapper.EasyBaseMapper;import com.wsh.mapper.EasyMapper;import com.wsh.entity.Order;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.Collection;@Servicepublic class EasyServiceImpl extends ServiceImpl implements EasyService{ @Override public Integer BatchSave(Collection orderList) { return baseMapper.insertBatchSomeColumn(orderList); }} 2.2 批量插入测试 package com.wsh;import com.wsh.entity.Order;import com.wsh.service.EasyServiceImpl;import org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;import java.util.ArrayList;import java.util.Date;@SpringBootTestpublic class TestEasyService { @Resource EasyServiceImpl easyService; @Test public void testBatchSave(){ long start = System.currentTimeMillis(); ArrayList orders = new ArrayList(); for (int i = 0; i