Mybatis-plus批量插入的2种方式总结

 更新时间:2023年08月08日 08:34:29   作者:厂长写代码  
这篇文章主要给大家总结介绍了关于Mybatis-plus批量插入的2种方式,Mybatis-Plus提供了多种方式进行批量插入优化,文中通过代码示例将实现的方法介绍的非常详细,需要的朋友可以参考下

前言

Mybatis-plus很强,为我们诞生了极简CURD操作,但对于数据批量操作,显然默认提供的insert方法是不够看的了,于是它和它来了!!! Mybatis-plus提供的两种插入方式

  • 继承IService(伪批量)
  • insertBatchSomeColumn 

一、继承IService(伪批量)

在Mapper继承BaseMapper<T>

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.UserStudy;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserStudyMapper extends BaseMapper<UserStudy> {
}

在Service中继承IService<T>

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.UserStudy;

/********************************************************************************
 ** @author : ZYJ
 ** @date :2023/04/20
 ** @description :厂长老婆催的睡觉了-批量插入Service
 *********************************************************************************/
public interface UserStudyService extends IService<UserStudy> {

}

在Service实现类继承ServiceImpl<M,T>

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.UserStudy;
import com.example.demo.mapper.UserStudyMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/********************************************************************************
 ** @author : ZYJ
 ** @date :2023/04/04
 ** @description :厂长加班写代码-批量插入
 *********************************************************************************/
@Service
public class UserStudyServiceImpl extends ServiceImpl<UserStudyMapper, UserStudy> implements UserStudyService {

    @Resource
    private UserStudyMapper userStudyMapper;

}

测试代码,调用IService的saveBatch方法

    /*
     *批量插入
     */
    @Override
    public void greatMany() {
        List<UserStudy> userStudyList = new ArrayList<>();
        UserStudy userStudy1 = new UserStudy();
        userStudy1.setName("张三");
        UserStudy userStudy2 = new UserStudy();
        userStudy2.setName("李四");
        userStudyList.add(userStudy1);
        userStudyList.add(userStudy2);
        //调用IService的saveBatch方法
        this.saveBatch(userStudyList);
    }

Mybatis-plus的SQL日志打印在配置文件application.yml配置

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志
#    log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl #关闭sql日志

测试结果,代码执行打印了两条SQL,所以可以看得出saveBatch底层也是遍历循环完成 

saveBatch方法分析

底层也是通过for来完成,默认是一个事务一次提交1000条数据,点击进入saveBatch可以看到, 也可以自定义每次提交多少条,自定义如下

        //调用IService的saveBatch方法
        this.saveBatch(userStudyList,2000);

二、insertBatchSomeColumn

自定义SQL注入器

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;

import java.util.List;

/********************************************************************************
 ** @author : ZYJ
 ** @date :2023/03/09
 ** @description :厂长加班写代码-批量插入SQL注入器
 *********************************************************************************/
public class InsertBatchSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        methodList.add(new InsertBatchSomeColumn()); //添加InsertBatchSomeColumn方法
        return methodList;
    }
}

把SQL注入器交给Spring

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class MybatisPlusConfig {
    /********************************************************************************
     ** @author : ZYJ
     ** @date :2023/04/14
     ** @description :注入配置
     *********************************************************************************/
    @Bean
    public InsertBatchSqlInjector easySqlInjector () {
        return new InsertBatchSqlInjector();
    }
}

到此定义完毕,在Mapper中生成insertBatchSomeColumn(必须是这个方法名)方法,你就可以撒手不管了,直接调用就行,或者直接在ServiceImpl通过Mapper调用insertBatchSomeColumn,然后ALT+回车生成此方法。

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.UserStudy;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface UserStudyMapper extends BaseMapper<UserStudy> {
    void insertBatchSomeColumn(@Param("list") List<UserStudy> userStudyList);
}

测试代码,调用insertBatchSomeColumn方法

    @Resource
    private UserStudyMapper userStudyMapper;
    /*
     *批量插入
     */
    @Override
    public void greatMany() {
        List<UserStudy> userStudyList = new ArrayList<>();
        UserStudy userStudy1 = new UserStudy();
        userStudy1.setName("张三");
        UserStudy userStudy2 = new UserStudy();
        userStudy2.setName("李四");
        userStudyList.add(userStudy1);
        userStudyList.add(userStudy2);
        //调用insertBatchSomeColumn方法
        userStudyMapper.insertBatchSomeColumn(userStudyList);
        //调用IService的saveBatch方法
        //this.saveBatch(userStudyList,2000);
    }

测试结果,代码执行打印一条SQL,所以可以看出是一条SQL便新增完成

注意:SQL有语句长度限制,在MySQL中被参数max_allowed_packet限制,默认为1M,如果拼接长度超过此限制就会报错,两种解决方式,一个是调整MySQL的max_allowed_packet 限制,另一个则是通过代码控制每次的提交数量。

通过代码控制每次提交数量,模拟造五条数据,每次提交两条数据

    /*
     *批量插入
     */
    @Override
    public void greatMany() {
        List<UserStudy> userStudyList = new ArrayList<>();
        UserStudy userStudy1 = new UserStudy();
        userStudy1.setName("张三");
        UserStudy userStudy2 = new UserStudy();
        userStudy2.setName("李四");
        UserStudy userStudy3 = new UserStudy();
        userStudy3.setName("王五");
        UserStudy userStudy4 = new UserStudy();
        userStudy4.setName("赵六");
        UserStudy userStudy5 = new UserStudy();
        userStudy5.setName("小红");
        userStudyList.add(userStudy1);
        userStudyList.add(userStudy2);
        userStudyList.add(userStudy3);
        userStudyList.add(userStudy4);
        userStudyList.add(userStudy5);
        //创建入库的list
        List<UserStudy> userStudyCount = new ArrayList<>();
        for (int i = 0; i < userStudyList.size(); i++) {
            //调用insertBatchSomeColumn方法
            userStudyCount.add(userStudyList.get(i));
            //控制每次提交数量
            if(userStudyCount.size()==2){
                userStudyMapper.insertBatchSomeColumn(userStudyCount);
                //将入库的list清空重新新增
                userStudyCount.clear();
            }
        }
        //将list中size不够2的数据在此处新增
        userStudyMapper.insertBatchSomeColumn(userStudyCount);
        //调用IService的saveBatch方法
        //this.saveBatch(userStudyList,2000);
    }

结果分析,五条数据应该请求三次新增,打印三条SQL,完美结束

总结:

默认的insert的方法对寻常业务来说是非常之高效,但对于批量数据的产生确实灾难性的,就是慢,很慢,巨慢,IService的saveBatch方法优于默认的insert方法,但是我选通过SQL注入器的方法insertBatchSomeColumn。

到此这篇关于Mybatis-plus批量插入的2种方式总结的文章就介绍到这了,更多相关Mybatis-plus批量插入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java并发编程之线程之间的共享和协作

    Java并发编程之线程之间的共享和协作

    这篇文章主要介绍了Java并发编程之线程之间的共享和协作,文中有非常详细的代码示例,对正在学习java的小伙伴们有一定的帮助,需要的朋友可以参考下
    2021-04-04
  • Java中HashMap如何解决哈希冲突

    Java中HashMap如何解决哈希冲突

    本文主要介绍了Java中HashMap如何解决哈希冲突,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • java实现AES 32位加密解密的方案

    java实现AES 32位加密解密的方案

    Oracle在其官方网站上提供了无政策限制权限文件(Unlimited Strength Jurisdiction Policy Files),我们只需要将其部署在JRE环境中,就可以解决限制问题,下面给大家介绍下java实现AES 32位加密解密的方案,感兴趣的朋友一起看看吧
    2021-11-11
  • 深入理解JSON及其在Java中的应用小结

    深入理解JSON及其在Java中的应用小结

    json它是一种轻量级的数据交换格式,由于其易于阅读和编写,同时也易于机器解析和生成,因此广泛应用于网络数据交换和配置文件,这篇文章主要介绍了深入理解JSON及其在Java中的应用,需要的朋友可以参考下
    2023-12-12
  • Java 队列Queue从原理到实战指南

    Java 队列Queue从原理到实战指南

    本文介绍了Java中队列(Queue)的底层实现、常见方法及其区别,通过LinkedList和ArrayDeque的实现,以及循环队列的概念,展示了如何高效地进行元素的入队、出队和查看操作,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • springboot项目防止XSS攻击和sql注入方式

    springboot项目防止XSS攻击和sql注入方式

    这篇文章主要介绍了springboot项目防止XSS攻击和sql注入方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 通过Class类获取对象(实例讲解)

    通过Class类获取对象(实例讲解)

    下面小编就为大家带来一篇通过Class类获取对象(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Spring中SpEL表达式的使用全解

    Spring中SpEL表达式的使用全解

    SpEL是Spring框架中用于表达式语言的一种方式,本文主要介绍了Spring中SpEL表达式的使用全解,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-04-04
  • Java多线程之死锁详解

    Java多线程之死锁详解

    这篇文章主要介绍了Java多线程的死锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-10-10
  • JAVA十大排序算法之桶排序详解

    JAVA十大排序算法之桶排序详解

    这篇文章主要介绍了java中的桶排序,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08

最新评论