
本系列参考黑马程序员微服务课程,有兴趣的可以去查看相关视频,本系列内容采用渐进式方式讲解微服务核心概念与实践方法,每日更新确保知识点的连贯性。通过系统化学习路径帮助开发者掌握分布式系统构建的关键技术。读者可通过平台订阅功能获取最新章节推送,及时了解服务拆分、容器化部署、服务网格等前沿技术动态。
- 个人主页:VON
- 文章所属专栏:微服务
- 系列文章链接:暂无
- 时间:每天12点准时更新
目录
前言
一、MyBatis-Plus 与 MyBatis 的区别
功能增强
开发效率
扩展性
适用场景
示例对比
二、引入Mybits-Plus
1.下载依赖
2.继承BaseMapper编辑
3、修改代码
4.测试
插入
查询 (单条数据)
查询 (多条数据)
更新数据
编辑 删除数据
三、常见注解
@TableName
示例:
@TableId
示例:
@TableField
常见的配置
四、条件构造器
1、基于QueryWrapper查询
2、基于UpdateWrapper更新
五、自定义SQL
六、Service接口
1、基础用法
2、实现简单业务接口
3、实现复杂业务接口
4.开始测试
(1)增加用户信息
(2)查询用户信息
(3)批量查询用户信息
(4)扣减用户余额
(5)删除用户信息
(6)根据Lambda查询用户信息
编辑
(7)IService批量新增
结语
前言
蝉鸣撕心裂肺时,VON从冷汗里弹起来。
泛黄的墙壁,潦草的名字,2030 年 7 月 15 日的日历 —— 这不是他被总监骂 "连 MybatisPlus 都不会" 的会议室。
他重生回了高考后的暑假。
前世因荒废假期,他在大学跟不上课程,工作后写几百行冗余 SQL 被嘲笑,看同事玩转微服务自己却连基础都摸不透。那些羞辱像针一样扎着。
班长的消息弹出来:"学长推荐了入门微服务的资料,从 MybatisPlus 开始。"
VON盯着那行字,心脏狂跳。前世他就是嫌难,把整个夏天耗在了游戏里。
"这次不能再错过。"
他抓起手机,点开前世屏蔽的技术公众号,目光落在《MybatisPlus 基础入门》上。窗外的蝉鸣突然温顺了,阳光在崭新的教程封面上,映出他眼里的光。
重生第一天,就从搞懂 MybatisPlus 开始。
一、MyBatis-Plus 与 MyBatis 的区别
Mybits-Plus官网
Mybits官网
MyBatis-Plus(简称 MP)是基于 MyBatis 的增强工具,旨在简化开发并提高效率,核心区别如下:
功能增强
MyBatis-Plus 在 MyBatis 基础上提供了大量开箱即用的功能:
- 自动化 CRUD:内置通用 Mapper 和 Service,无需手动编写基础 SQL。
- 条件构造器:通过
QueryWrapper、UpdateWrapper等实现动态 SQL 拼接。 - 代码生成器:自动生成实体类、Mapper、Service 等代码。
- 分页插件:内置分页支持,无需额外配置。
开发效率
MyBatis 需要手动编写 SQL 和结果映射,而 MyBatis-Plus 通过约定优于配置减少冗余代码:
- 默认映射实体类与数据库表字段(支持驼峰转换)。
- 提供 Lambda 表达式写法,避免硬编码字段名。
扩展性
- MyBatis-Plus 完全兼容原生 MyBatis,可混合使用。
- 支持自定义全局操作(如逻辑删除、自动填充字段)。
适用场景
- MyBatis:需高度定制复杂 SQL 或已有成熟 MyBatis 项目。
- MyBatis-Plus:快速开发常规业务(如后台管理系统),减少样板代码。
示例对比
MyBatis 示例:
MyBatis-Plus 等价操作:
二、引入Mybits-Plus
1.下载依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency>
2.继承BaseMapper
3、修改代码
原来代码👇

将原来代码中的语句直接删除

Mapper也同理

修改测试类中的方法即可,根据提示直接回车即可
4.测试
插入

插入成功

查询 (单条数据)

查询 (多条数据)

更新数据
删除数据

由此可见增删改查功能全部正常,目前的代码极大的简化了原本的代码
三、常见注解
@TableName
用于指定实体类对应的数据库表名。当实体类名与数据库表名不一致时,使用该注解进行映射。
@TableName("user_info")
public class User {// 类字段
}
示例:

@TableId
用于标识主键字段,并可以指定主键生成策略。常见的属性包括value(数据库主键字段名)和type(主键生成策略)。
@TableId(value = "id", type = IdType.AUTO)
private Long id;
主键生成策略(IdType)常见选项:
AUTO:数据库自增INPUT:手动输入ASSIGN_ID:雪花算法生成IDASSIGN_UUID:生成UUID
示例:
这里测试一下自增

@TableField
用于标注非主键字段,解决字段名与数据库列名不一致的问题,或标识非表字段(如 transient 字段)。
@TableField("user_name")
private String name;@TableField(exist = false)
private String tempData;
常见属性:
value:数据库字段名(默认与属性名一致时可不填)exist:是否为数据库字段(默认为true)fill:字段自动填充策略(如FieldFill.INSERT插入时填充)
注:当exist设置为false时该字段不显示

注:在数据库设计或查询中,偶尔会遇到表名与数据库保留关键字相同的情况。这可能导致语法错误或执行失败。以下是几种常见的解决方法:
使用引号或方括号包裹表名 不同数据库系统对保留关键字的处理方式不同。MySQL使用反引号(`),SQL Server使用方括号([]),PostgreSQL和Oracle使用双引号("")。例如:
-- MySQL
SELECT * FROM `order`;-- SQL Server
SELECT * FROM [order];-- PostgreSQL/Oracle
SELECT * FROM "order";
修改表名 避免使用数据库保留关键字作为表名是最佳实践。可以通过添加前缀或后缀来修改表名,例如tbl_order或orders。
使用别名 在查询中为表指定别名可以避免直接使用关键字。例如:
SELECT o.* FROM `order` AS o WHERE o.id = 1;
数据库保留关键字列表 不同数据库系统的保留关键字各不相同。
常见的配置
mybitis-plus:# 配置Mapper XML文件的位置mapper-locations: classpath*:mapper/*.xmlconfiguration:# 开启下划线转驼峰命名映射map-underscore-to-camel-case: true# 指定MyBatis日志实现方式,输出到控制台log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 关闭二级缓存cache-enabled: falseglobal-config:db-config:# 主键生成策略:自动递增id-type: auto# 逻辑删除字段名logic-delete-field: is_deleted# 逻辑删除值(标记为已删除)logic-delete-value: 1# 逻辑未删除值(标记为未删除)logic-not-delete-value: 0# 逻辑删除列名logic-delete-column: is_deleted# 逻辑删除类型为列模式logic-delete-type: COLUMN# 数据库类型db-type: mysql# 表前缀table-prefix: tbl_# 字段策略:智能判断非空字段field-strategy: smart# 更新策略:智能判断非空字段update-strategy: smart# 插入策略:智能判断非空字段insert-strategy: smart
一般配置成这样就可以了

想要了解更多的可以看官方文档👇
文章开头部分已经引入了文档官网

四、条件构造器
1、基于QueryWrapper查询
//条件构造器测试案例@Testvoid textOne1(){//查询名字带o,并且存款大于1000的用户List<User> users = userMapper.selectList(new QueryWrapper<User>().like("username", "o").gt("balance", 1000));users.forEach(System.out::println);}@Testvoid textOne2(){//将张三存款改为10000User user = new User();user.setBalance(10000);QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "张a三");userMapper.update(user, wrapper);}
可见查询到了一条符合的语句
可见余额已经修改为10000了

2、基于UpdateWrapper更新
@Testvoid textTwo1(){//基于UpdateWrapper更新id为1,2,3的用户余额减500UpdateWrapper<User> wrapper = new UpdateWrapper<User>().in("id", 1, 2, 3).setSql("balance = balance - 500");userMapper.update(null, wrapper);}
更新前的数据如下

更新后的数据
五、自定义SQL
这种写法是 “用分层设计让代码更干净,用动态条件适配变化,用 XML 管好 SQL ,用测试保障质量” ,本质是为了让数据库操作的 “开发更灵活、维护更简单、协作更顺畅、质量更可控”

测试用例驱动(功能触发层)
编写 textCustomSqlQuery 测试方法,先定义更新参数(用户 ID 列表 ids、扣除金额 amount ),再用 QueryWrapper 构建 id IN (1,2,3) 的条件,最后调用 userMapper.updateBalanceByIds ,作为功能入口触发数据库操作。
Mapper 接口约定(方法声明层)
在 UserMapper 接口中定义 updateBalanceByIds 方法,通过 @Param 明确入参(条件 wrapper、金额 amount ),约定参数传递规则,作为 XML 映射 SQL 的 “调用声明”。
XML 映射执行(SQL 实现层)
XML 中通过 <update id="updateBalanceByIds"> 绑定接口方法,编写 SQL :UPDATE tb_user SET balance = balance - #{amount} ${ew.customSqlSegment} ,既用 #{amount} 安全传参,又通过 ${ew.customSqlSegment} 拼接条件,最终在数据库执行 “按 ID 批量扣余额” 的更新。
测试用例负责场景触发,Mapper 接口定义调用契约,XML 映射实现具体 SQL ,协同完成数据库更新逻辑。
六、Service接口
1、基础用法
只需继承一下接口即可

这里做一个简单的测试

直接就可以对数据库中的数据进行修改

2、实现简单业务接口

添加配置文件
<!--swagger--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.1.0</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
修改yaml文件,加入以下代码
knife4j:enable: trueopenapi:group:default:group-name: defaultapi-rule: packageapi-rule-resources:- com.itheima.mp.controller
添加UserVO和UserFormDTO两个实体类


开始写Controller代码
package com.itheima.mp.controller;import cn.hutool.core.bean.BeanUtil;
import com.itheima.mp.domain.dto.UserFormDTO;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;import java.util.List;@Api(tags = "用户管理相关接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {private final IUserService userService;@ApiOperation("新增用户")@PostMappingpublic void saveUser(@RequestBody UserFormDTO userDTO){//1.把DTO转换成POUser user = BeanUtil.copyProperties(userDTO,User.class);//2.调用service完成新增userService.save(user);}@ApiOperation("删除用户")@DeleteMapping("/{id}")public void deleteUserById(@ApiParam("用户id") @PathVariable("id") Long id){userService.removeById(id);}@ApiOperation("查询用户")@GetMapping("/{id}")public UserVO queryUserById(@ApiParam("用户id") @PathVariable("id") Long id){//1.查询用户POUser user = userService.getById(id);//2.把PO转换成VOreturn BeanUtil.copyProperties(user,UserVO.class);}@ApiOperation("批量查询用户")@GetMapping("/{id}")public List<UserVO> queryUserByIds(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids){//1.查询用户POList<User> users = userService.listByIds(ids);//2.把PO转换成VOreturn BeanUtil.copyToList(users,UserVO.class);}
}
3、实现复杂业务接口
这里的请求方式是PUT请求,这里写错了,留意一下
最后一行的id应该是id的,这里写成ew了🤡🤡🤡

4.开始测试
这里用的是Apifox
(1)增加用户信息

发送post请求
成功插入数据
(2)查询用户信息
注意下这里是GET请求

(3)批量查询用户信息

(4)扣减用户余额
这里是PUT请求

这里扣减id为5的用户

余额变成9000了
(5)删除用户信息
删除id为7的用户

可以看到id为7的用户被删除了

以上的测试后端也都响应回来了

(6)根据Lambda查询用户信息
先创建一个实体类,参数多的情况下不建议一个一个输入
controller和service层代码

注意下这里的请求路径为了和上文区分改成了list
看下实体类中的参数,都可以进行查询



这里的状态码全为1,所以没有查询到状态码为2的。

细心的话不难发现2号余额为负数
先将他的余额设置成100,然后在减余额
这里的逻辑改了一下,用户余额为0时会改变状态,也就是冻结用户

调整好代码后接着测试扣减余额
注意下这里的请求方式和参数

可以看到状态和余额都改变了

(7)IService批量新增

注:这里需要打开mysql的一个参数

将这个字段设置为true即可。
结语
这篇关于 MyBatis - Plus 学习的文章,其诞生如同一场与代码世界的深度邂逅。从暮色浸染的傍晚 6 点,到星光缀满夜空的凌晨 0:37,除去 30 分钟短暂的用餐时光,近 6 小时的全神贯注,最终打磨出这篇约 7000 字的学习记录。
每一个字符都凝结着对 MyBatis - Plus 知识点的反复推敲,每一步操作过程的呈现都力求精准还原技术实践,每一处运行结果的记录都饱含对细节的极致追求 —— 这份从指尖流淌而出的文字,不仅是时间的沉淀,更是对 MyBatis - Plus 实操细节的细致捕捉。
唯愿这份带着钻研热忱与满满诚意的记录,能为正在学习 MyBatis - Plus 的你扫清障碍,提供切实的参考与助益,让你的学习之路更顺畅。
最后附上文章全套代码
代码参考黑马程序员资料

UserController
package com.itheima.mp.controller;import cn.hutool.core.bean.BeanUtil;
import com.itheima.mp.domain.dto.UserFormDTO;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.query.UserQuery;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;import java.util.List;@Api(tags = "用户管理相关接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {private final IUserService userService;@ApiOperation("新增用户")@PostMappingpublic void saveUser(@RequestBody UserFormDTO userDTO){//1.把DTO转换成POUser user = BeanUtil.copyProperties(userDTO,User.class);//2.调用service完成新增userService.save(user);}@ApiOperation("删除用户")@DeleteMapping("/{id}")public void deleteUserById(@ApiParam("用户id") @PathVariable("id") Long id){userService.removeById(id);}@ApiOperation("查询用户")@GetMapping("/{id}")public UserVO queryUserById(@ApiParam("用户id") @PathVariable("id") Long id){//1.查询用户POUser user = userService.getById(id);//2.把PO转换成VOreturn BeanUtil.copyProperties(user,UserVO.class);}@ApiOperation("批量查询用户")@GetMappingpublic List<UserVO> queryUserByIds(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids){//1.查询用户POList<User> users = userService.listByIds(ids);//2.把PO转换成VOreturn BeanUtil.copyToList(users,UserVO.class);}@ApiOperation("扣减余额")@PutMapping("/{id}/deduction/{money}")public void deductBalance(@ApiParam("用户id") @PathVariable("id") Long id,@ApiParam("金额") @PathVariable("money") Integer money){userService.deductBalance(id,money);}@ApiOperation("根据复杂条件查询用户")@GetMapping("/list")public List<UserVO> queryUserByIds(UserQuery query){//1.查询用户POList<User> users = userService.queryUsers(query.getName(),query.getStatus(),query.getMinBalance(),query.getMaxBalance());//2.把PO转换成VOreturn BeanUtil.copyToList(users,UserVO.class);}
}
User
package com.itheima.mp.domain.po;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.time.LocalDateTime;
@TableName("tb_user")
@Data
public class User {/*** 用户id*/private Long id;/*** 用户名*/private String username;/*** 密码*/private String password;/*** 注册手机号*/private String phone;/*** 详细信息*/private String info;/*** 使用状态(1正常 2冻结)*/private Integer status;/*** 账户余额*/private Integer balance;/*** 创建时间*/private LocalDateTime createTime;/*** 更新时间*/private LocalDateTime updateTime;
}
UserQuery
package com.itheima.mp.domain.query;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery {@ApiModelProperty("用户名关键字")private String name;@ApiModelProperty("用户状态:1-正常,2-冻结")private Integer status;@ApiModelProperty("余额最小值")private Integer minBalance;@ApiModelProperty("余额最大值")private Integer maxBalance;
}
UserVO
package com.itheima.mp.domain.vo;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "用户VO实体")
public class UserVO {@ApiModelProperty("用户id")private Long id;@ApiModelProperty("用户名")private String username;@ApiModelProperty("详细信息")private String info;@ApiModelProperty("使用状态(1正常 2冻结)")private Integer status;@ApiModelProperty("账户余额")private Integer balance;
}
UserMapper
package com.itheima.mp.mapper;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.springframework.core.Constants;import java.util.List;public interface UserMapper extends BaseMapper<User> {
// List<User> queryUserByIds(@Param("ids") List<Long> ids);void updateBalanceByIds(@Param("ew") QueryWrapper<User> wrapper, @Param("amount") int amount);@Update("update tb_user set balance = balance - #{money} where id = #{id}")void deductBalance(@Param("id") Long id, @Param("money") Integer money);
}
UserServiceImpl
package com.itheima.mp.service.impl;import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Override@Transactionalpublic void deductBalance(Long id, Integer money) {//1.查询用户User user = getById(id);//2.更新用户余额if(user == null || user.getStatus() == 2){throw new RuntimeException("用户不存在");}if(user.getBalance() < money){throw new RuntimeException("余额不足");}//余额为0时冻结用户int remainBalance = user.getBalance() - money;lambdaUpdate().set(User::getBalance, remainBalance).set(remainBalance == 0, User::getStatus, 2).eq(User::getBalance,user.getBalance()).eq(User::getId, id).update();}@Overridepublic List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {return lambdaQuery().like(name!=null, User::getUsername, name).eq(status!=null, User::getStatus, status).ge(minBalance!=null, User::getBalance, minBalance).le(maxBalance!=null, User::getBalance, maxBalance).list();}
}
IUserService
package com.itheima.mp.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;import java.util.List;public interface IUserService extends IService<User> {void deductBalance(Long id, Integer money);List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance);
}
yaml
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=truetype: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456
logging:level:com.itheima: debugpattern:dateformat: HH:mm:ss
#mybatis:
# mapper-locations: classpath*:mapper/*.xml
mybitis-plus:mapper-locations: classpath*:mapper/*.xmlconfiguration:map-underscore-to-camel-case: truecache-enabled: falseglobal-config:db-config:id-type: autoupdate-strategy: not_null
knife4j:enable: trueopenapi:group:default:group-name: defaultapi-rule: packageapi-rule-resources:- com.itheima.mp.controller
UserMapperTest
package com.itheima.mp.mapper;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDateTime;
import java.util.List;@SpringBootTest
class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid testInsert() {User user = new User();//user.setId(5L);user.setUsername("张a三");user.setPassword("123");user.setPhone("18688990012");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userMapper.insert(user);}@Testvoid testSelectById() {User user = userMapper.selectById(5L);System.out.println("user = " + user);}@Testvoid testQueryByIds() {List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));users.forEach(System.out::println);}@Testvoid testUpdateById() {User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);}@Testvoid testDeleteUser() {userMapper.deleteById(5L);}//条件构造器测试案例@Testvoid textOne1() {//查询名字带o,并且存款大于1000的用户List<User> users = userMapper.selectList(new QueryWrapper<User>().like("username", "o").gt("balance", 1000));users.forEach(System.out::println);}@Testvoid textOne2() {//将张三存款改为10000User user = new User();user.setBalance(10000);QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "张a三");userMapper.update(user, wrapper);}@Testvoid textTwo1() {//基于UpdateWrapper更新id为1,2,3的用户余额减500UpdateWrapper<User> wrapper = new UpdateWrapper<User>().in("id", 1, 2, 3).setSql("balance = balance - 500");userMapper.update(null, wrapper);}@Testvoid textCustomSqlQuery() {//1.更新条件List<Long> ids = List.of(1L, 2L, 3L);int amount = 100;//2.定义条件QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id", ids);//3.调用 方法userMapper.updateBalanceByIds(wrapper, amount);}
}
IUserServiceTest
package com.itheima.mp.service;import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestExecutionListeners;import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class IUserServiceTest {@Autowiredprivate IUserService userService;@Testvoid testSaveUser(){User user = new User();//user.setId(5L);user.setUsername("张三aaa");user.setPassword("123");user.setPhone("18688990012");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userService.save(user);}@Testvoid testQuery(){List<User> list = userService.listByIds(List.of(1L, 2L, 3L));list.forEach(System.out::println);}@Testvoid testSaveBatch(){List<User> list = new ArrayList<>(10000);long b = System.currentTimeMillis();for (int i = 1; i <= 100000; i++) {User user = new User();user.setUsername("user" + i);user.setPassword("<PASSWORD>");user.setPhone("12345678901");user.setStatus(1);user.setBalance(100);user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());list.add(user);if(i%10000==0){userService.saveBatch(list);list.clear();}}long e = System.currentTimeMillis();System.out.println("耗时:"+(e-b));}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.itheima.mp</groupId><artifactId>mp-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>mp-demo</name><description>Demo project for Spring Boot</description><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>2.3.1</version>-->
<!-- </dependency>-->
<!-- mybits plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><!--swagger--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.1.0</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.11</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
