经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MyBatis » 查看文章
一文了解MyBatis Plus批量数据插入功能
来源:jb51  时间:2021/9/27 11:06:02  对本文有异议

前言

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

  1. /**
  2. * 插入操作
  3. */
  4. @RequestMapping("/save")
  5. public Object save() {
  6. boolean flag = false; // 返回结果
  7. // 待添加(用户)数据
  8. for (int i = 0; i < 1000; i++) {
  9. User user = new User();
  10. user.setName("test:"+i);
  11. user.setPassword("123456");
  12. // 插入数据
  13. flag = userService.save(user);
  14. if(!flag) break;
  15. }
  16. return flag;
  17. }

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

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

批量插入实现方案

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

1.引入 MP 框架

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

  1. <dependency>
  2. <groupId>com.baomidou</groupId>
  3. <artifactId>mybatis-plus-boot-starter</artifactId>
  4. <version>mybatis-plus-latest-version</version>
  5. </dependency>

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

2.创建数据库和表

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

  1. -- ----------------------------
  2. -- 创建数据库
  3. -- ----------------------------
  4. SET NAMES utf8mb4;
  5. SET FOREIGN_KEY_CHECKS = 0;
  6. DROP DATABASE IF EXISTS `testdb`;
  7. CREATE DATABASE `testdb`;
  8. USE `testdb`;
  9.  
  10. -- ----------------------------
  11. -- 创建 user
  12. -- ----------------------------
  13. DROP TABLE IF EXISTS `user`;
  14. CREATE TABLE `user` (
  15. `id` int(11) NOT NULL AUTO_INCREMENT,
  16. `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  17. `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  18. `createtime` datetime NULL DEFAULT CURRENT_TIMESTAMP,
  19. PRIMARY KEY (`id`) USING BTREE
  20. ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;
  21.  
  22. -- ----------------------------
  23. -- 添加测试数据
  24. -- ----------------------------
  25. INSERT INTO `user` VALUES (1, '赵云', '123456', '2021-09-10 18:11:16');
  26. INSERT INTO `user` VALUES (2, '张飞', '123456', '2021-09-10 18:11:28');
  27. INSERT INTO `user` VALUES (3, '关羽', '123456', '2021-09-10 18:11:34');
  28. INSERT INTO `user` VALUES (4, '刘备', '123456', '2021-09-10 18:11:41');
  29. INSERT INTO `user` VALUES (5, '曹操', '123456', '2021-09-10 18:12:02');
  30.  
  31. SET FOREIGN_KEY_CHECKS = 1;
  32.  

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

① 实体类

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

  1. import lombok.Getter;
  2. import lombok.Setter;
  3.  
  4. import java.util.Date;
  5.  
  6. @Getter
  7. @Setter
  8. public class User {
  9. private int id;
  10. private String name;
  11. private String password;
  12. private Date createtime;
  13. }
  14.  

② Controller 层代码

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

  1. import com.example.demo.model.User;
  2. import com.example.demo.service.impl.UserServiceImpl;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6.  
  7. import java.util.ArrayList;
  8. import java.util.List;
  9.  
  10. @RestController
  11. @RequestMapping("/u")
  12. public class UserController {
  13.  
  14. @Autowired
  15. private UserServiceImpl userService;
  16.  
  17. /**
  18. * MP 批量插入
  19. */
  20. @RequestMapping("/savebatch")
  21. public boolean saveBatch() {
  22. List<User> list = new ArrayList<>();
  23. // 待添加(用户)数据
  24. for (int i = 0; i < 1000; i++) {
  25. User user = new User();
  26. user.setName("test:"+i);
  27. user.setPassword("123456");
  28. list.add(user);
  29. }
  30. // 批量插入
  31. return userService.saveBatch(list);
  32. }
  33. }
  34.  

③ Service 层代码(重点)

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

  1. import com.baomidou.mybatisplus.extension.service.IService;
  2. import com.example.demo.model.User;
  3.  
  4. public interface UserService extends IService<User> {
  5.  
  6. }
  7.  

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

  1. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  2. import com.example.demo.mapper.UserMapper;
  3. import com.example.demo.model.User;
  4. import com.example.demo.service.UserService;
  5. import org.springframework.stereotype.Service;
  6.  
  7. @Service
  8. public class UserServiceImpl extends ServiceImpl<UserMapper,User>
  9. implements UserService {
  10.  
  11. }
  12.  

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

④ Mapper 层代码

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

  1. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  2. import com.example.demo.model.User;
  3. import org.apache.ibatis.annotations.Mapper;
  4.  
  5. @Mapper
  6. public interface UserMapper extends BaseMapper<User>{
  7.  
  8. }
  9.  

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

总结

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号