最近 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@Setterpublic 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;@Servicepublic 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;@Mapperpublic interface UserMapper extends BaseMapper<User>{}
PS:BaseMapper 提供了对某个对象(类)最根底的 CRUD 操作。
总结
本文咱们介绍了 MP(MyBatis Plus)中实现批量插入的具体实现步骤,它的外围是通过调用 MP 中 IService 提供的 saveBatch 办法来实现的,但如果我的项目中没有引入 MP 框架该如何解决?是不是应用了 MP 就能够躺平了呢?不焦急,下篇咱们再聊批量插入的另一种形式(原生批量插入的实现形式),以及二者之间的优缺点剖析。
关注公众号「Java中文社群」查看更多 MyBatis 和 Spring Boot 的系列文章。