> 技术文档 > 重生之我在暑假学习微服务第一天《MybatisPlus-上篇》_要学习微服务的话,mybatis-plus需要学吗

重生之我在暑假学习微服务第一天《MybatisPlus-上篇》_要学习微服务的话,mybatis-plus需要学吗

 

本系列参考黑马程序员微服务课程,有兴趣的可以去查看相关视频,本系列内容采用渐进式方式讲解微服务核心概念与实践方法,每日更新确保知识点的连贯性。通过系统化学习路径帮助开发者掌握分布式系统构建的关键技术。读者可通过平台订阅功能获取最新章节推送,及时了解服务拆分、容器化部署、服务网格等前沿技术动态。

  •  个人主页: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。
  • 条件构造器:通过 QueryWrapperUpdateWrapper 等实现动态 SQL 拼接。
  • 代码生成器:自动生成实体类、Mapper、Service 等代码。
  • 分页插件:内置分页支持,无需额外配置。

开发效率

MyBatis 需要手动编写 SQL 和结果映射,而 MyBatis-Plus 通过约定优于配置减少冗余代码:

  • 默认映射实体类与数据库表字段(支持驼峰转换)。
  • 提供 Lambda 表达式写法,避免硬编码字段名。

扩展性

  • MyBatis-Plus 完全兼容原生 MyBatis,可混合使用。
  • 支持自定义全局操作(如逻辑删除、自动填充字段)。

适用场景

  • MyBatis:需高度定制复杂 SQL 或已有成熟 MyBatis 项目。
  • MyBatis-Plus:快速开发常规业务(如后台管理系统),减少样板代码。

示例对比

MyBatis 示例

MyBatis-Plus 等价操作

二、引入Mybits-Plus

1.下载依赖

 com.baomidou mybatis-plus-boot-starter 3.5.3.1

 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:雪花算法生成ID
  • ASSIGN_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使用双引号(\"\")。例如:

-- MySQLSELECT * FROM `order`;-- SQL ServerSELECT * FROM [order];-- PostgreSQL/OracleSELECT * FROM \"order\";

修改表名 避免使用数据库保留关键字作为表名是最佳实践。可以通过添加前缀或后缀来修改表名,例如tbl_orderorders

使用别名 在查询中为表指定别名可以避免直接使用关键字。例如:

SELECT o.* FROM `order` AS o WHERE o.id = 1;

数据库保留关键字列表 不同数据库系统的保留关键字各不相同。

常见的配置

mybitis-plus: # 配置Mapper XML文件的位置 mapper-locations: classpath*:mapper/*.xml configuration: # 开启下划线转驼峰命名映射 map-underscore-to-camel-case: true # 指定MyBatis日志实现方式,输出到控制台 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 关闭二级缓存 cache-enabled: false global-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查询

//条件构造器测试案例 @Test void textOne1(){ //查询名字带o,并且存款大于1000的用户 List users = userMapper.selectList(new QueryWrapper().like(\"username\", \"o\").gt(\"balance\", 1000)); users.forEach(System.out::println); } @Test void textOne2(){ //将张三存款改为10000 User user = new User(); user.setBalance(10000); QueryWrapper wrapper = new QueryWrapper().eq(\"username\", \"张a三\"); userMapper.update(user, wrapper); }

 可见查询到了一条符合的语句

 可见余额已经修改为10000了

 2、基于UpdateWrapper更新

@Test void textTwo1(){ //基于UpdateWrapper更新id为1,2,3的用户余额减500 UpdateWrapper wrapper = new UpdateWrapper().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 中通过  绑定接口方法,编写 SQL :UPDATE tb_user SET balance = balance - #{amount} ${ew.customSqlSegment} ,既用 #{amount} 安全传参,又通过 ${ew.customSqlSegment} 拼接条件,最终在数据库执行 “按 ID 批量扣余额” 的更新。

测试用例负责场景触发,Mapper 接口定义调用契约,XML 映射实现具体 SQL ,协同完成数据库更新逻辑。

六、Service接口

1、基础用法

只需继承一下接口即可

这里做一个简单的测试

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

2、实现简单业务接口

 添加配置文件

  com.github.xiaoymin knife4j-openapi2-spring-boot-starter 4.1.0    org.springframework.boot spring-boot-starter-web 

修改yaml文件,加入以下代码

knife4j: enable: true openapi: group: default: group-name: default api-rule: package api-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@RequiredArgsConstructorpublic class UserController { private final IUserService userService; @ApiOperation(\"新增用户\") @PostMapping public void saveUser(@RequestBody UserFormDTO userDTO){ //1.把DTO转换成PO User 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.查询用户PO User user = userService.getById(id); //2.把PO转换成VO return BeanUtil.copyProperties(user,UserVO.class); } @ApiOperation(\"批量查询用户\") @GetMapping(\"/{id}\") public List queryUserByIds(@ApiParam(\"用户id集合\") @RequestParam(\"ids\") List ids){ //1.查询用户PO List users = userService.listByIds(ids); //2.把PO转换成VO return 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@RequiredArgsConstructorpublic class UserController { private final IUserService userService; @ApiOperation(\"新增用户\") @PostMapping public void saveUser(@RequestBody UserFormDTO userDTO){ //1.把DTO转换成PO User 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.查询用户PO User user = userService.getById(id); //2.把PO转换成VO return BeanUtil.copyProperties(user,UserVO.class); } @ApiOperation(\"批量查询用户\") @GetMapping public List queryUserByIds(@ApiParam(\"用户id集合\") @RequestParam(\"ids\") List ids){ //1.查询用户PO List users = userService.listByIds(ids); //2.把PO转换成VO return 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 queryUserByIds(UserQuery query){ //1.查询用户PO List users = userService.queryUsers(query.getName(),query.getStatus(),query.getMinBalance(),query.getMaxBalance()); //2.把PO转换成VO return 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\")@Datapublic 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 {// List queryUserByIds(@Param(\"ids\") List ids); void updateBalanceByIds(@Param(\"ew\") QueryWrapper 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;@Servicepublic class UserServiceImpl extends ServiceImpl implements IUserService { @Override @Transactional public 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(); } @Override public List 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 { void deductBalance(Long id, Integer money); List 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=true type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456logging: level: com.itheima: debug pattern: dateformat: HH:mm:ss#mybatis:# mapper-locations: classpath*:mapper/*.xmlmybitis-plus: mapper-locations: classpath*:mapper/*.xml configuration: map-underscore-to-camel-case: true cache-enabled: false global-config: db-config: id-type: auto update-strategy: not_nullknife4j: enable: true openapi: group: default: group-name: default api-rule: package api-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;@SpringBootTestclass UserMapperTest { @Autowired private UserMapper userMapper; @Test void 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); } @Test void testSelectById() { User user = userMapper.selectById(5L); System.out.println(\"user = \" + user); } @Test void testQueryByIds() { List users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L)); users.forEach(System.out::println); } @Test void testUpdateById() { User user = new User(); user.setId(5L); user.setBalance(20000); userMapper.updateById(user); } @Test void testDeleteUser() { userMapper.deleteById(5L); } //条件构造器测试案例 @Test void textOne1() { //查询名字带o,并且存款大于1000的用户 List users = userMapper.selectList(new QueryWrapper().like(\"username\", \"o\").gt(\"balance\", 1000)); users.forEach(System.out::println); } @Test void textOne2() { //将张三存款改为10000 User user = new User(); user.setBalance(10000); QueryWrapper wrapper = new QueryWrapper().eq(\"username\", \"张a三\"); userMapper.update(user, wrapper); } @Test void textTwo1() { //基于UpdateWrapper更新id为1,2,3的用户余额减500 UpdateWrapper wrapper = new UpdateWrapper().in(\"id\", 1, 2, 3).setSql(\"balance = balance - 500\"); userMapper.update(null, wrapper); } @Test void textCustomSqlQuery() { //1.更新条件 List ids = List.of(1L, 2L, 3L); int amount = 100; //2.定义条件 QueryWrapper wrapper = new QueryWrapper().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.*;@SpringBootTestclass IUserServiceTest { @Autowired private IUserService userService; @Test void 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); } @Test void testQuery(){ List list = userService.listByIds(List.of(1L, 2L, 3L)); list.forEach(System.out::println); } @Test void testSaveBatch(){ List 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(\"\"); 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

 4.0.0  org.springframework.boot spring-boot-starter-parent 2.7.12    com.itheima.mp mp-demo 0.0.1-SNAPSHOT mp-demo Demo project for Spring Boot  11    org.springframework.boot spring-boot-starter   com.mysql mysql-connector-j runtime   org.projectlombok lombok true   org.springframework.boot spring-boot-starter-test test <!-- --><!-- org.mybatis.spring.boot--><!-- mybatis-spring-boot-starter--><!-- 2.3.1--><!-- -->  com.baomidou mybatis-plus-boot-starter 3.5.3.1    com.github.xiaoymin knife4j-openapi2-spring-boot-starter 4.1.0    org.springframework.boot spring-boot-starter-web   cn.hutool hutool-all 5.8.11      org.springframework.boot spring-boot-maven-plugin     org.projectlombok lombok