作者 | 王磊

来源 | Java中文社群(ID:javacn666)

转载请联系授权(微信ID:GG_Stone

最近 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 {@Autowiredprivate 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 就可以躺平了呢?

不着急,下篇我们再聊批量插入的另一种方式(原生批量插入的实现方式),以及二者之间的优缺点分析。

MyBatis Plus 批量数据插入功能,yyds!相关推荐

  1. excel 复制数据 sql server 粘贴_一个Excel妙招,一个SQL技巧,解决批量数据插入问题

    #Excel技巧# #数据库# #MySQL# 业务背景 不知道您在工作中有没有遇到过这样几种情况: 业务定期给你一批数据结构相同的名单或者数据,要求你插入到库里并进行处理. 机器学习指标加工时,一个 ...

  2. mysql 批量数据插入很慢(kettle 输入输出组件) 性能优化办法

    背景 最近在做数仓重构项目,遇到一些性能瓶颈,这里记录一下解决办法. 随着业务数据每天都在增加,几年前开发的etl任务开始跑不动了.大表一般是通过增量的方式插入,但是修复bug 或者每月/季度跑一次的 ...

  3. 扩展tk.mybatis的批量更新的功能

    tk.mybatis没有带批量更新的功能,批量更新却是经常使用的,所以需要自己实现. 批量更新网上主要有2种方式:case when方式.foreach方式 但是foreachzhe这种方式效率非常低 ...

  4. mysql插入多行数据来自另一张表_mysql从一张表查询批量数据并插入到另一表中的完整实例...

    说在前面 nodejs 读取数据库是一个异步操作,所以在数据库还未读取到数据之前,就会继续往下执行代码. 最近写东西时,需要对数据库进行批量数据的查询后,insert到另一表中. 说到批量操作,让人最 ...

  5. linq 清除一条数据中的某个字段值_B端通用批量数据导入方案设计

    点击上方蓝色字体,关注我 B端通用批量数据导入方案设计 文 | 3548字 估计阅读 | 9分钟 引题 B端产品经常遇到大量数据录入的需求.如春季招聘完成后,给新招的120个员工建立员工档案,并创建员 ...

  6. MySQL 批量插入,如何不插入重复数据?根据条件 MyBatis不插入重复数据

    目录 前言 解决方案 1.insert ignore into 2.on duplicate key update 3.insert - select - where not exist 4.repl ...

  7. list mybatis批量保存_mybatis 批量将list数据插入到数据库的实现

    随着业务需要,有时我们需要将数据批量添加到数据库,mybatis提供了将list集合循环添加到数据库的方法.具体实现代码如下: 1.mapper层中创建 insertForeach(List < ...

  8. mybatis 批量将list数据插入到数据库

    mybatis 批量将list数据插入到数据库 <select id="selectExistsLightName" parameterType="java.uti ...

  9. Java通过Mybatis实现批量插入数据到Oracle中

    最近项目中遇到一个问题:导入数据到后台并将数据插入到数据库中,导入的数据量有上万条数据,考虑采用批量插入数据的方式: 结合网上资料,写了个小demo,文章末尾附上demo下载地址 1.新建项目:项目目 ...

最新文章

  1. ADO.Net练习1
  2. XScuGic_Connect分析
  3. 解决 502、504 Gateway Time-out(nginx)
  4. python 连 mongodb
  5. sping jdbc 链接mysql_Spring Boot JDBC 连接数据库示例
  6. 直接修改html文本页面没变化,VUE 直接通过JS 修改html对象的值导致没有更新到数据中解决方法分析...
  7. 信息学奥赛一本通(1014:与圆相关的计算)
  8. Qt 实现Windows系统Win10 c++音量调节
  9. 乒乓球:浅析业余高手从输球中总结的10条心得!
  10. 如何让工作更有活力?社科院与杜兰大学金融管理硕士项目帮你充电续航
  11. excel验证身份证号码是否正确
  12. 操作系统——进程的状态与转换
  13. 怎样使表格中的数字自动计算机,直观:Excel电子表格一次打印入场数据-Excel如何将数字设置为每次打印时自动递增...
  14. java如何实现对word设置只读或者加密
  15. python绘制地图的第三方库,geopandas,用python画地图原来这么简单!
  16. 前端CSS移动端适配
  17. DoEvents的用法
  18. word文档图标变成白纸_word图标变了_word图标变成白底方框
  19. 比尔盖兹的十一项人生建议
  20. java的class文件批量反编译成java

热门文章

  1. 2021 最新 IDEA集成Gitee、Gitee迁移GitHub【图文讲解】
  2. python环境快速安装opencv 离线版安装
  3. Anuglar中正确导入RxJS库
  4. Script:List OBJECT DEPENDENT
  5. 【iCore4 双核心板_FPGA】例程十六:基于双口RAM的ARM+FPGA数据存取实验
  6. ES6的class方法基本用法
  7. Android特效 五种Toast具体解释
  8. 正则表达式 使用分支
  9. 常见的排序算法二——希尔排序
  10. 多核分布式队列的实现:“偷”与“自私”的运用(1)