一文了解MyBatis Plus批量数据插入功能

目录
  • 前言
  • 批量插入实现方案
    • 1.引入 MP 框架
    • 2.创建数据库和表
    • 3.具体代码实现(重点)
  • 总结

前言

最近 Review 小伙伴代码的时候,发现了一个小小的问题,小伙伴竟然在 for 循环中进行了 insert (插入)数据库的操作,这就会导致每次循环时都会进行连接、插入、断开连接的操作,从而导致一定的性能问题,简化后代码如下:

/**
 * 插入操作
 */
@RequestMapping("/save")
public Object save() {
    boolean flag = false; // 返回结果
    // 待添加(用户)数据
    for (int i = 0; i < 1000; i++) {
        User user = new User();
        user.setName("test:"+i);
        user.setPassword("123456");
        // 插入数据
        flag = userService.save(user);
        if(!flag) break;
    }
    return flag;
}

这样做并不会改变程序最终的执行结果,但会对程序的执行效率带来很大的影响,就好比你现在要从 A 地点送 10 件货到 B 地点,你可以选择 1 次送 1 件,送 10 次的方案;也可以选择 1 次送 10 件,送 1 次的方案,请问你会选择哪种?这就是多次循环插入和批量一次插入的问题。​

PS:要插入的数据量越大,批量插入的时间(相比于循环多次插入来说)也越短、其优势也越大。

批量插入实现方案

本文我们使用 MyBatis-Plus(下文简称 MP)自带的 saveBatch 方法,来实现数据的批量插入功能,因为 MP 不是本文讨论的重点,所以这里咱们就不介绍了,如果有不熟悉的朋友可以去他的官方自行恶补:https://baomidou.com/guide/,咱们本文重点介绍一下 MP 实现批量插入的具体步骤。

1.引入 MP 框架

首先,打开您的 pom.xml 文件,在文件中添加以下内容:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>mybatis-plus-latest-version</version>
</dependency>

注意:mybatis-plus-latest-version 表示 MP 框架的最新版本号,可访问 https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter 查询最新版本号,但在使用的时候记得一定要将上面的 “mybatis-plus-latest-version”替换成换成具体的版本号,如 3.4.3 才能正常的引入框架。

2.创建数据库和表

此步骤可省略,主要用于本文功能的实现,创建数据库和数据表的脚本如下:

-- ----------------------------
-- 创建数据库
-- ----------------------------
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP DATABASE IF EXISTS `testdb`;
CREATE DATABASE `testdb`;
USE `testdb`;

-- ----------------------------
-- 创建 user 表
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `createtime` datetime NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;

-- ----------------------------
-- 添加测试数据
-- ----------------------------
INSERT INTO `user` VALUES (1, '赵云', '123456', '2021-09-10 18:11:16');
INSERT INTO `user` VALUES (2, '张飞', '123456', '2021-09-10 18:11:28');
INSERT INTO `user` VALUES (3, '关羽', '123456', '2021-09-10 18:11:34');
INSERT INTO `user` VALUES (4, '刘备', '123456', '2021-09-10 18:11:41');
INSERT INTO `user` VALUES (5, '曹操', '123456', '2021-09-10 18:12:02');

SET FOREIGN_KEY_CHECKS = 1;

3.具体代码实现(重点)

① 实体类

先来创建数据库所对应的 User 实体类:

import lombok.Getter;
import lombok.Setter;

import java.util.Date;

@Getter
@Setter
public class User {
    private int id;
    private String name;
    private String password;
    private Date createtime;
}

② Controller 层代码

本文的核心是使用 MP 框架中,IService 类提供的 saveBatch 方法,来实现批量数据的插入功能,对应在 Controller 中的实现代码如下:

import com.example.demo.model.User;
import com.example.demo.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/u")
public class UserController {

    @Autowired
    private UserServiceImpl userService;

    /**
     * MP 批量插入
     */
    @RequestMapping("/savebatch")
    public boolean saveBatch() {
        List<User> list = new ArrayList<>();
        // 待添加(用户)数据
        for (int i = 0; i < 1000; i++) {
            User user = new User();
            user.setName("test:"+i);
            user.setPassword("123456");
            list.add(user);
        }
        // 批量插入
        return userService.saveBatch(list);
    }
}

③ Service 层代码(重点)

接下来,我们要创建一个 UserService 接口,继承 MP 框架中的 IService 接口,实现代码如下:

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.model.User;

public interface UserService extends IService<User> {

}

然后再创建一个 UserService 的实现类:

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User>
        implements UserService {

}

PS:注意 UserServiceImpl 必须要继承 MP 框架中的 ServiceImpl,不然要重写很多方法。

④ Mapper 层代码

Mapper 层的实现相对来说就比较简单了,只需要创建一个 Mapper 类继承 MP 框架中的 BaseMapper 类即可,实现代码如下:

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

@Mapper
public interface UserMapper extends BaseMapper<User>{

}

PS:BaseMapper 提供了对某个对象(类)最基础的 CRUD 操作。

总结

本文我们介绍了 MP(MyBatis Plus)中实现批量插入的具体实现步骤,它的核心是通过调用 MP 中 IService 提供的 saveBatch 方法来完成的,但如果项目中没有引入 MP 框架该如何处理?是不是使用了 MP 就可以躺平了呢?不着急,下篇我们再聊批量插入的另一种方式(原生批量插入的实现方式),以及二者之间的优缺点分析。

(0)

相关推荐

  • 给你的MyBatis-Plus装上批量插入的翅膀(推荐)

    前言 各位好,我是易哥(thinkYi). 大家有用过MyBatis-Plus(简称MP)的都知道它是一个MyBatis的增强工具,旨在MyBatis的基础上只做增强不做改变,为简化开发.提高效率而生. 特点 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 强大的 CRUD 操作:内置通用 Mapper.通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足

  • Mybatis Plus 实现批量插入的示例代码

    目录 一. 添加依赖 二. 继承默认方法注入 三. 在 MybatisPlusConfig 配置文件中注入 Bean 四. 扩展自带 BaseMapper 五. 业务层面实现 Mybatis Plus 的 IService 接口中提供了批量插入的方法,然而,它的内部实现逻辑竟然是这样的: 居然是循环单条插入?!逗人玩嘛,好吧,自己动手,丰衣足食. 一. 添加依赖 <!--mybatis plus extension,包含了mybatis plus core--> <dependency&

  • MyBatis-Plus 批量插入数据的操作方法

    spring boot+mybatis plus环境,单条插入用的是BaseMapper自带的insert方法 public ApiResult addAnc(Anc anc) { ApiResult result = new ApiResult(); Integer insert = ancMapper.insert(anc); if (insert < 1) { return result.failed("发布失败,请联系管理员"); } return result.succ

  • mybatisPlus自定义批量新增的实现代码

    mybatisPlus底层的新增方法是一条一条的新增的,今天自定义批量新增方法. 创建自定义数据方法注入类 /** * @Description: EasySqlInjector 自定义数据方法注入 * @Author WangYejian * @Date: 2020/11/4 14:34 */ public class EasySqlInjector extends DefaultSqlInjector { @Override public List<AbstractMethod> getM

  • mybatisplus添加真正的批量新增、批量更新的实现

    使用mybatis-plus来进行批量新增和更新时,你会发现其实是一条条sql执行,下面进行优化. 1.添加InsertBatchMethod和UpdateBatchMethod类 import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.metadata.TableInfo; import lombok.extern.slf4j.Slf4j; import

  • 一文了解MyBatis Plus批量数据插入功能

    目录 前言 批量插入实现方案 1.引入 MP 框架 2.创建数据库和表 3.具体代码实现(重点) 总结 前言 最近 Review 小伙伴代码的时候,发现了一个小小的问题,小伙伴竟然在 for 循环中进行了 insert (插入)数据库的操作,这就会导致每次循环时都会进行连接.插入.断开连接的操作,从而导致一定的性能问题,简化后代码如下: /** * 插入操作 */ @RequestMapping("/save") public Object save() { boolean flag

  • 详解扩展tk.mybatis的批量更新的功能

    tk.mybatis没有带批量更新的功能,批量更新却是经常使用的,所以需要自己实现. 批量更新网上主要有2种方式:case when方式.foreach方式 但是foreachzhe这种方式效率非常低下,不知道为何那多么帖子在流传,请看我另一个文章. 扩展tk.mybatis的批量更新,采用case when方式,源码干货如下: 首先定义下mapper接口 import org.apache.ibatis.annotations.UpdateProvider; import java.util.

  • Spring Boot使用线程池处理上万条数据插入功能

    目录 # 前言 # 使用步骤 # 前言 前两天做项目的时候,想提高一下插入表的性能优化,因为是两张表,先插旧的表,紧接着插新的表,一万多条数据就有点慢了 后面就想到了线程池ThreadPoolExecutor,而用的是Spring Boot项目,可以用Spring提供的对ThreadPoolExecutor封装的线程池ThreadPoolTaskExecutor,直接使用注解启用 # 使用步骤 先创建一个线程池的配置,让Spring Boot加载,用来定义如何创建一个ThreadPoolTask

  • 使用postgresql 模拟批量数据插入的案例

    创建表: CREATE TABLE t_test( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL ); 模拟批量插入: insert into t_test SELECT generate_series(1,5000000) as key,repeat( chr(int4(random()*26)+65),4), (random()*(6^2))::

  • mysql从一张表查询批量数据并插入到另一表中的完整实例

    说在前面 nodejs 读取数据库是一个异步操作,所以在数据库还未读取到数据之前,就会继续往下执行代码. 最近写东西时,需要对数据库进行批量数据的查询后,insert到另一表中. 说到批量操作,让人最容易想到的是for循环. 错误的 for 循环版本 先放出代码,提前说明一下,在这里封装了sql操作:sql.sever(数据库连接池,sql语句拼接函数,回调函数) for(let i=0;i<views.xuehao.length;i++){ sql.sever(pool,sql.select(

  • mybatis foreach批量插入数据:Oracle与MySQL区别介绍

    下面给大家介绍mybatis foreach批量插入数据:Oracle与MySQL不同点: •主要不同点在于foreach标签内separator属性的设置问题: •separator设置为","分割时,最终拼接的代码形式为:insert into table_name (a,b,c) values (v1,v2,v3) ,(v4,v5,v6) ,... •separator设置为"union all"分割时,最终拼接的代码形式为:insert into table

  • mybatis 批量将list数据插入到数据库的实现

    随着业务需要,有时我们需要将数据批量添加到数据库,mybatis提供了将list集合循环添加到数据库的方法.具体实现代码如下: 1.mapper层中创建 insertForeach(List < Fund > list) 方法,返回值是批量添加的数据条数 package com.center.manager.mapper; import java.util.List; import org.apache.ibatis.annotations.Mapper; import com.center.

  • 浅谈MyBatis原生批量插入的坑与解决方案

    目录 原生批量插入的"坑" 解决方案 分片 Demo 实战 原生批量插入分片实现 总结 前面的文章咱们讲了 MyBatis 批量插入的 3 种方法:循环单次插入.MyBatis Plus 批量插入.MyBatis 原生批量插入,详情请点击<MyBatis 批量插入数据的 3 种方法!> 但之前的文章也有不完美之处,原因在于:使用 「循环单次插入」的性能太低,使用「MyBatis Plus 批量插入」性能还行,但要额外的引入 MyBatis Plus 框架,使用「MyBati

  • mybatis中批量插入的两种方式(高效插入)

    MyBatis简介 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录. 一.mybiats foreach标签 foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合.foreach元素的属性主

  • Oracle + Mybatis实现批量插入、更新和删除示例代码

    前言 Mybatis是web工程开发中非常常用的数据持久化的框架,通过该框架,我们非常容易的进行数据库的增删改查.数据库连接进行事务提交的时候,需要耗费的资源比较多,如果需要插入更新的数据比较多,而且每次事务只提交一条数据,会造成非常大的数据库资源浪费,导致数据库性能.系统性能大幅度下降. 关于mybatis的批量插入,网上的多数示例多半是关于MySQL数据库的,关于Oracle数据库的例子比较少.本文将给大家介绍关于Oracle+Mybatis批量插入.更新和删除的相关内容,下面话不多说了,来

随机推荐