MyBatis的五种批量插入详解

 更新时间:2023年08月25日 09:10:24   作者:谁是黄黄  
这篇文章主要介绍了MyBatis的五种批量插入详解,MyBatis是一款半自动的ORM持久层框架,具有较高的SQL灵活性,支持高级映射(一对一,一对多),动态SQL,延迟加载和缓存等特性,但它的数据库无关性较低,需要的朋友可以参考下

MyBatis

MyBatis是一款半自动的ORM持久层框架,具有较高的SQL灵活性,支持高级映射(一对一,一对多),动态SQL,延迟加载和缓存等特性,但它的数据库无关性较低

用mybatis进行开发,需要手动编写SQL语句。而全自动的ORM框架,如hibernate,则不需要编写SQL语句。

用hibernate开发,只需要定义好ORM映射关系,就可以直接进行CRUD操作了。

由于mybatis需要手写SQL语句,所以它有较高的灵活性,可以根据需要,自由地对SQL进行定制,也因为要手写SQL,当要切换数据库时,SQL语句可能就要重写,因为不同的数据库有不同的方言(Dialect),所以mybatis的数据库无关性低。

一.直接循环插入

@RestController
@RequestMapping("/mybatis3/user")
@RequiredArgsConstructor
public class UserController {
    private final IUserService iUserService;
    @GetMapping("/one")
    public Long one(){
       return iUserService.add();
    }
}
  Long add();
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    private final UserMapper userMapper;
    @Override
    public Long add() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            User user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            userMapper.insertUsers(user);
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }
    }
 Integer insertUsers(User user);
 <insert id="insertUsers" >
        insert into user(username,password)
        values (#{username}, #{password})
    </insert>

最终耗时:14s多

在这里插入图片描述

二.关闭MySql自动提交,手动进行循环插入提交

@RestController
@RequestMapping("/mybatis3/user")
@RequiredArgsConstructor
public class UserController {
    private final IUserService iUserService;
        @GetMapping("/one")
    public Long one(){
       return iUserService.add();
    }
}
 Long add2();
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    private final UserMapper userMapper;
//    手动开启sql的批量提交
    private final   SqlSessionTemplate sqlSessionTemplate;
    @Override
    public Long add2(){
        //关闭自动提交
        SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            User user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            mapper.insertUsers(user);
        }
        //自动提交SQL
        sqlSession.commit();
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }
    }

平均:0.12s

在这里插入图片描述

第三种:用List集合的方式插入数据库(推荐)

@RestController
@RequestMapping("/mybatis3/user")
@RequiredArgsConstructor
public class UserController {
    private final IUserService iUserService;
       @GetMapping("/one3")
    public Long one3(){
        return iUserService.add3();
    }
}
  Long add3();
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    private final UserMapper userMapper;
  @Override
    public Long add3(){
        long start = System.currentTimeMillis();
        List<User> userList = new ArrayList<>();
        User user;
        for (int i = 0; i < 10000; i++) {
            user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            userList.add(user);
        }
        userMapper.insertUsersThree(userList);
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }
    }
 Integer insertUsersThree(List<User> userList);
<insert id="insertUsersThree">
        insert into user(username,password)
        values
        <foreach collection="userList" item="user" separator=",">
            (#{user.username},#{user.password})
        </foreach>
    </insert>

第四种: MyBatis-Plus提供的SaveBatch方法

@RestController
@RequestMapping("/mybatis3/user")
@RequiredArgsConstructor
public class UserController {
    private final IUserService iUserService;
@GetMapping("/one4")
    public Long one4(){
        return iUserService.add4();
    }
}
  Long add4();
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    private final UserMapper userMapper;
@Override
    public Long add4() {
        long start = System.currentTimeMillis();
        List<User> userList= new ArrayList<>();
        User user ;
        for (int i = 0; i < 10000; i++) {
            user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            userList.add(user);
        }
        saveBatch(userList);
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }
    }

直接报错:

在这里插入图片描述

看报错信息:

长串:Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: com.huang.mybatis3.mapper.UserMapper.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Data truncation: Out of range value for column ‘id’ at row 1 ; Data truncation: Out of range value for column ‘id’ at row 1; nested exception is java.sql.BatchUpdateException: Data truncation: Out of range value for column ‘id’ at row 1] with root cause

短串:Data truncation: Out of range value for column ‘id’ at row 1

翻译一下:

在这里插入图片描述

可以发现就是我们的id超出范围:

在这里插入图片描述

int类型改为bigint即可

故此我们可以得出一个结论:设置数据库id的时候设置为bigint还是蛮好的哈

平均时间:0.2s

在这里插入图片描述

第五种 MyBatis-Plus提供的InsertBatchSomeColumn方法(推荐)

InsertBatchSomeColumn方法了解

在这里插入图片描述

这个类的注解就写的很明白

扩展这个InsertBatchSomeColumn方法

@Slf4j
public class EasySqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        // 注意:此SQL注入器继承了DefaultSqlInjector(默认注入器),调用了DefaultSqlInjector的getMethodList方法,保留了mybatis-plus的自带方法
        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
        methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
        log.info("扩展的getMethodList方法被框架调用了");
        return methodList;
    }
}

扩展的方法注入bean容器

/**
 * @author Stone
 * @date 2023/1/3
 * @apiNote
 */
@Configuration
public class MybatisPlusConfig {
    @Bean
    public  EasySqlInjector sqlInjector(){
        return new EasySqlInjector();
    }
}

创建一个Mapper去实现我们的扩展的飞方法

public interface EasySqlInjectMapper<T> extends BaseMapper<T> {
    /**
     * 批量插入 仅适用于mysql
     *
     * @param entityList 实体列表
     * @return 影响行数
     */
    Integer insertBatchSomeColumn(Collection<T> entityList);
}

业务层

 @Override
    public Long add5() {
        long start = System.currentTimeMillis();
        List<User> userList= new ArrayList<>();
        User user ;
        for (int i = 0; i < 10000; i++) {
            user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            userList.add(user);
        }
        userMapper.insertBatchSomeColumn(userList);
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }

耗时: 0.2 s

在这里插入图片描述

到此这篇关于MyBatis的五种批量插入详解的文章就介绍到这了,更多相关MyBatis的批量插入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 你可能真没用过这些 IDEA 插件(建议收藏)

    你可能真没用过这些 IDEA 插件(建议收藏)

    IDEA 全称 IntelliJ IDEA,是java编程语言开发的集成环境。IntelliJ在业界被公认为最好的java开发工具。这篇文章主要介绍 IDEA 必用插件的安装及用法,需要的朋友可以参考下
    2020-08-08
  • Java禁止使用finalize方法

    Java禁止使用finalize方法

    这篇文章主要介绍了Java禁止使用finalize方法,需要的朋友可以参考下
    2017-10-10
  • IDEA创建SpringBoot的maven项目的方法步骤

    IDEA创建SpringBoot的maven项目的方法步骤

    这篇文章主要介绍了IDEA创建SpringBoot的maven项目的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • JavaWeb实现文件上传下载功能实例解析

    JavaWeb实现文件上传下载功能实例解析

    这篇文章主要为大家详细介绍了JavaWeb中的文件上传和下载功能的实现,在Web应用系统开发中,文件上传和下载功能是非常常用的功能,需要的朋友可以参考下
    2015-08-08
  • Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别

    Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别

    关于FactoryBean 和 BeanFactory的对比文章比较多,但是对ObjectFactory的描述就比较少,今天我们对比下这三种的区别,感兴趣的朋友跟随小编一起看看吧
    2023-01-01
  • Java通过关闭Socket终止线程

    Java通过关闭Socket终止线程

    这篇文章主要为大家详细介绍了Java通过关闭Socket终止线程的相关代码
    2017-04-04
  • SpringMVC 数据校验实例解析

    SpringMVC 数据校验实例解析

    这篇文章主要介绍了SpringMVC 数据校验实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java ArrayAdapter用法案例详解

    Java ArrayAdapter用法案例详解

    这篇文章主要介绍了Java ArrayAdapter用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • Struts2拦截器登录验证实例

    Struts2拦截器登录验证实例

    本篇文章主要介绍了Struts2拦截器登录验证实例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • Java Socket实现聊天室附1500行源代码

    Java Socket实现聊天室附1500行源代码

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。本篇文章手把手带你通过Java Socket来实现自己的聊天室,大家可以在过程中查缺补漏,温故而知新
    2021-10-10

最新评论