• 面试官:MyBatis批量插入的五种方式,哪种最强?


    前言
    

    这里我列举了MyBatis和MyBatis-Plus常用的五种批量插入的方式,进行了详细的总结归纳,写的非常详细,整体思路清晰明了,只分享干货。

    • 准备工作

    • MyBatis利用For循环批量插入

    • MyBatis的手动批量提交

    • MyBatis以集合方式批量新增(推荐)

    • MyBatis-Plus提供的SaveBatch方法

    • MyBatis-Plus提供的InsertBatchSomeColumn方法(推荐)

    • 总结

    一、准备工作

    1、导入pom.xml依赖

    1. <dependency>
    2.     <groupId>mysql</groupId>
    3.     <artifactId>mysql-connector-java</artifactId>
    4.     <scope>runtime</scope>
    5. </dependency>
    6. <!--Mybatis依赖-->
    7. <dependency>
    8.     <groupId>org.mybatis.spring.boot</groupId>
    9.     <artifactId>mybatis-spring-boot-starter</artifactId>
    10.     <version>2.2.2</version>
    11. </dependency>
    12. <!--Mybatis-Plus依赖-->
    13. <dependency>
    14.     <groupId>com.baomidou</groupId>
    15.     <artifactId>mybatis-plus-boot-starter</artifactId>
    16.     <version>3.5.2</version>
    17. </dependency>
    18. <dependency>
    19.     <groupId>org.projectlombok</groupId>
    20.     <artifactId>lombok</artifactId>
    21.     <optional>true</optional>
    22. </dependency>

    2、配置yml文件

    1. server:
    2.   port: 8080
    3.  
    4. spring:
    5.   datasource:
    6.     username: mysql用户名
    7.     password: mysql密码
    8.     url: jdbc:mysql://localhost:3306/数据库名字?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    9.     driver-class-name: com.mysql.cj.jdbc.Driver
    10.  
    11. mybatis:
    12.   mapper-locations: classpath:mapping/*.xml

    3、公用的User类

    1. @Data
    2. public class User {
    3.  
    4.     private int id;
    5.     private String username;
    6.     private String password;
    7. }

    二、MyBatis利用For循环批量插入

    1、编写UserService服务类,测试一万条数据耗时情况

    1. @Service
    2. public class UserService {
    3.  
    4.     @Resource
    5.     private UserMapper userMapper;
    6.  
    7.     public void InsertUsers(){
    8.         long start = System.currentTimeMillis();
    9.         for(int i = 0 ;i < 10000; i++) {
    10.             User user = new User();
    11.             user.setUsername("name" + i);
    12.             user.setPassword("password" + i);
    13.             userMapper.insertUsers(user);
    14.         }
    15.         long end = System.currentTimeMillis();
    16.         System.out.println("一万条数据总耗时:" + (end-start+ "ms" );
    17.     }
    18.  
    19. }

    2、编写UserMapper接口

    1. @Mapper
    2. public interface UserMapper {
    3.  
    4.     Integer insertUsers(User user);
    5. }

    3、编写UserMapper.xml文件

    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.ithuang.demo.mapper.UserMapper">
    6.     <insert id="insertUsers">
    7.         INSERT INTO user (username, password)
    8.         VALUES(#{username}, #{password})
    9.     insert>
    10. mapper>

    4、进行单元测试

    1. @SpringBootTest
    2. class DemoApplicationTests {
    3.  
    4.     @Resource
    5.     private UserService userService;
    6.  
    7.     @Test
    8.     public void insert(){
    9.         userService.InsertUsers();
    10.     }
    11.  
    12. }

    5、结果输出

    一万条数据总耗时:26348ms

    三、MyBatis的手动批量提交

    1、其他保持不变,Service层作稍微的变化

    1. @Service
    2. public class UserService {
    3.  
    4.     @Resource
    5.     private UserMapper userMapper;
    6.  
    7.     @Resource
    8.     private SqlSessionTemplate sqlSessionTemplate;
    9.  
    10.     public void InsertUsers(){
    11.         //关闭自动提交
    12.         SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
    13.         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    14.         long start = System.currentTimeMillis();
    15.         for(int i = 0 ;i < 10000; i++) {
    16.             User user = new User();
    17.             user.setUsername("name" + i);
    18.             user.setPassword("password" + i);
    19.             userMapper.insertUsers(user);
    20.         }
    21.         sqlSession.commit();
    22.         long end = System.currentTimeMillis();
    23.         System.out.println("一万条数据总耗时:" + (end-start+ "ms" );
    24.     }
    25.  
    26. }

    2、结果输出

    一万条数据总耗时:24516ms

    四、MyBatis以集合方式批量新增(推荐)

    1、编写UserService服务类

    1. @Service
    2. public class UserService {
    3.  
    4.     @Resource
    5.     private UserMapper userMapper;
    6.  
    7.     public void InsertUsers(){
    8.         long start = System.currentTimeMillis();
    9.         List<User> userList = new ArrayList<>();
    10.         User user;
    11.         for(int i = 0 ;i < 10000; i++) {
    12.             user = new User();
    13.             user.setUsername("name" + i);
    14.             user.setPassword("password" + i);
    15.             userList.add(user);
    16.         }
    17.         userMapper.insertUsers(userList);
    18.         long end = System.currentTimeMillis();
    19.         System.out.println("一万条数据总耗时:" + (end-start+ "ms" );
    20.     }
    21.  
    22. }

    2、编写UserMapper接口

    1. @Mapper
    2. public interface UserMapper {
    3.  
    4.     Integer insertUsers(List userList);
    5. }

    3、编写UserMapper.xml文件

    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.ithuang.demo.mapper.UserMapper">
    6.     <insert id="insertUsers">
    7.         INSERT INTO user (username, password)
    8.         VALUES
    9.         <foreach collection ="userList" item="user" separator =",">
    10.             (#{user.username}, #{user.password})
    11.         foreach>
    12.     insert>
    13. mapper>

    4、输出结果

    一万条数据总耗时:521ms

    五、MyBatis-Plus提供的SaveBatch方法

    1、编写UserService服务

    1. @Service
    2. public class UserService extends ServiceImpl<UserMapper, User> implements IService<User> {
    3.  
    4.     public void InsertUsers(){
    5.         long start = System.currentTimeMillis();
    6.         List<User> userList = new ArrayList<>();
    7.         User user;
    8.         for(int i = 0 ;i < 10000; i++) {
    9.             user = new User();
    10.             user.setUsername("name" + i);
    11.             user.setPassword("password" + i);
    12.             userList.add(user);
    13.         }
    14.         saveBatch(userList);
    15.         long end = System.currentTimeMillis();
    16.         System.out.println("一万条数据总耗时:" + (end-start+ "ms" );
    17.     }
    18. }

    2、编写UserMapper接口

    1. @Mapper
    2. public interface UserMapper extends BaseMapper<User> {
    3.  
    4. }

    3、单元测试结果

    一万条数据总耗时:24674ms

    六、MyBatis-Plus提供的InsertBatchSomeColumn方法(推荐)

    1、编写EasySqlInjector 自定义类

    1. public class EasySqlInjector extends DefaultSqlInjector {
    2.  
    3.  
    4.     @Override
    5.     public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
    6.         // 注意:此SQL注入器继承了DefaultSqlInjector(默认注入器),调用了DefaultSqlInjector的getMethodList方法,保留了mybatis-plus的自带方法
    7.         List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
    8.         methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
    9.         return methodList;
    10.     }
    11.  
    12. }

    2、定义核心配置类注入此Bean

    1. @Configuration
    2. public class MybatisPlusConfig {
    3.  
    4.     @Bean
    5.     public EasySqlInjector sqlInjector() {
    6.         return new EasySqlInjector();
    7.     }
    8. }

    3、编写UserService服务类

    1. public class UserService{
    2.  
    3.     @Resource
    4.     private UserMapper userMapper;
    5.     public void InsertUsers(){
    6.         long start = System.currentTimeMillis();
    7.         List<User> userList = new ArrayList<>();
    8.         User user;
    9.         for(int i = 0 ;i < 10000; i++) {
    10.             user = new User();
    11.             user.setUsername("name" + i);
    12.             user.setPassword("password" + i);
    13.             userList.add(user);
    14.         }
    15.         userMapper.insertBatchSomeColumn(userList);
    16.         long end = System.currentTimeMillis();
    17.         System.out.println("一万条数据总耗时:" + (end-start+ "ms" );
    18.     }
    19. }

    4、编写EasyBaseMapper接口

    1. public interface EasyBaseMapper<T> extends BaseMapper<T> {
    2.     /**
    3.      * 批量插入 仅适用于mysql
    4.      *
    5.      * @param entityList 实体列表
    6.      * @return 影响行数
    7.      */
    8.     Integer insertBatchSomeColumn(Collection<T> entityList);
    9. }

    5、编写UserMapper接口

    1. @Mapper
    2. public interface UserMapper<T> extends EasyBaseMapper<User> {
    3.     
    4. }

    6、单元测试结果

    一万条数据总耗时:575ms

    七、总结

    以上就是我对目前MyBatis常用的批量插入方法的总结

  • 相关阅读:
    OpenGL概述(核心模式与立即模式、扩展、OpenGL中的对象)
    【中级网络工程师】下午网络配置题
    centos7.6 修改vi /etc/security/limits.conf ,不生效问题
    MySQL日志系统知识点总结
    白话数据结构之基本概念篇(6)_查找算法
    Airflow架构与扩容
    企业清算有哪些类型?在哪里可以查看相关公告?
    AI界的宝藏图:揭秘最牛AI网站,轻松成为智能科技达人!
    nSoftware IPWorks 2022 Java 22.0.8 Crack
    开源ERP和CRM套件Dolibarr
  • 原文地址:https://blog.csdn.net/m0_71777195/article/details/128181541