MyBatis-Plus 核心功能详解:条件构造器、Service 封装与批量优化实践(黑马springcloud微服务课程)(day2)

MyBatis-Plus 核心功能详解:条件构造器、Service 封装与批量优化实践

在日常开发中,简单的基于 id 的 CRUD 并不能满足复杂业务需求。MyBatis-Plus 在 BaseMapper 的基础上,提供了条件构造器(Wrapper)通用 Service 层封装 以及高效批量处理能力,可以极大提升开发效率与代码可维护性。本文将系统总结这些核心能力,并结合实际示例进行说明。
上一节课的内容:MyBatis-Plus 快速入门与常用注解、配置总结

📚 目录(点击跳转对应章节)

一、条件构造器(Wrapper)
[二、QueryWrapper 与 UpdateWrapper 的使用](#二、QueryWrapper 与 UpdateWrapper 的使用)
[三、LambdaQueryWrapper 与 LambdaUpdateWrapper](#三、LambdaQueryWrapper 与 LambdaUpdateWrapper)
[四、自定义 SQL 与 Wrapper 结合使用](#四、自定义 SQL 与 Wrapper 结合使用)
[五、Service 层封装(IService & ServiceImpl)](#五、Service 层封装(IService & ServiceImpl))
[六、基于 Lambda 的动态条件查询](#六、基于 Lambda 的动态条件查询)
[七、LambdaUpdate 实现复杂业务更新](#七、LambdaUpdate 实现复杂业务更新)
八、批量新增性能优化
九、总结


一、条件构造器(Wrapper)

在 MyBatis-Plus 中,除了新增操作外,修改、删除、查询 都需要 WHERE 条件。BaseMapper 不仅支持基于 id 的操作,还支持通过 Wrapper 条件构造器实现复杂 SQL。

1. Wrapper 体系结构

  • Wrapper:条件构造的顶层抽象类
  • AbstractWrapper:提供所有 WHERE 条件的通用构造方法
  • QueryWrapper:在 AbstractWrapper 基础上扩展了 select,用于指定查询字段
  • UpdateWrapper:在 AbstractWrapper 基础上扩展了 set,用于构建 SET 语句

二、QueryWrapper 与 UpdateWrapper 的使用

1. QueryWrapper 查询示例

需求 :查询用户名中包含 o,且余额大于等于 1000 的用户。

java 复制代码
QueryWrapper<User> wrapper = new QueryWrapper<User>()
        .select("id", "username", "info", "balance")
        .like("username", "o")
        .ge("balance", 1000);

List<User> users = userMapper.selectList(wrapper);

2. QueryWrapper 更新示例

需求 :将用户名为 Jack 的用户余额修改为 2000。

java 复制代码
QueryWrapper<User> wrapper = new QueryWrapper<User>()
        .eq("username", "Jack");

User user = new User();
user.setBalance(2000);

userMapper.update(user, wrapper);

3. UpdateWrapper:基于原值更新字段

需求:对 id 为 1、2、4 的用户,余额统一扣减 200。

对应 SQL:

sql 复制代码
UPDATE user SET balance = balance - 200 WHERE id IN (1,2,4);

使用 UpdateWrapper#setSql

java 复制代码
UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
        .setSql("balance = balance - 200")
        .in("id", List.of(1L, 2L, 4L));

userMapper.update(null, wrapper);

三、LambdaQueryWrapper 与 LambdaUpdateWrapper

1. 解决字符串魔法值问题

QueryWrapperUpdateWrapper 需要手写字段名字符串,不利于维护。MyBatis-Plus 提供了 Lambda Wrapper,通过方法引用自动解析字段名。

2. LambdaQueryWrapper 示例

java 复制代码
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.lambda()
        .select(User::getId, User::getUsername, User::getInfo, User::getBalance)
        .like(User::getUsername, "o")
        .ge(User::getBalance, 1000);

List<User> users = userMapper.selectList(wrapper);

四、自定义 SQL 与 Wrapper 结合使用

1. Wrapper + 注解 SQL

当业务不允许在 Service 层直接拼 SQL,可将 SQL 定义在 Mapper 中,并使用 Wrapper 生成条件。

java 复制代码
@Update("UPDATE user SET balance = balance - #{money} ${ew.customSqlSegment}")
void deductBalanceByIds(@Param("money") int money,
                        @Param("ew") QueryWrapper<User> wrapper);

调用方式:

java 复制代码
QueryWrapper<User> wrapper = new QueryWrapper<User>()
        .in("id", List.of(1L, 2L, 4L));

userMapper.deductBalanceByIds(200, wrapper);

2. 多表关联查询

MyBatis-Plus 不直接支持多表查询,但可通过 自定义 SQL + Wrapper 条件实现。

java 复制代码
QueryWrapper<User> wrapper = new QueryWrapper<User>()
        .in("u.id", List.of(1L, 2L, 4L))
        .eq("a.city", "北京");

Mapper:

java 复制代码
@Select("SELECT u.* FROM user u INNER JOIN address a ON u.id = a.user_id ${ew.customSqlSegment}")
List<User> queryUserByWrapper(@Param("ew") QueryWrapper<User> wrapper);

五、Service 层封装(IService & ServiceImpl)

MyBatis-Plus 提供了通用的 Service 接口 IService,以及默认实现 ServiceImpl,封装了常见业务方法:

  • save / saveBatch / saveOrUpdate
  • remove / update
  • get / list / count / page
  • lambdaQuery / lambdaUpdate

1. 自定义 Service

java 复制代码
public interface IUserService extends IService<User> {
    void deductBalance(Long id, Integer money);
}

实现类:

java 复制代码
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements IUserService {
}

六、基于 Lambda 的动态条件查询

1. 动态查询条件实体

java 复制代码
public class UserQuery {
    private String name;
    private Integer status;
    private Integer minBalance;
    private Integer maxBalance;
}

2. lambdaQuery 链式查询

java 复制代码
List<User> users = userService.lambdaQuery()
        .like(query.getName() != null, User::getUsername, query.getName())
        .eq(query.getStatus() != null, User::getStatus, query.getStatus())
        .ge(query.getMinBalance() != null, User::getBalance, query.getMinBalance())
        .le(query.getMaxBalance() != null, User::getBalance, query.getMaxBalance())
        .list();

这种写法等价于 MyBatis 的 <if> 动态 SQL,代码更简洁、可读性更强。


七、LambdaUpdate 实现复杂业务更新

需求:扣减余额后,如果余额为 0,则将用户状态修改为冻结。

java 复制代码
lambdaUpdate()
        .set(User::getBalance, remainBalance)
        .set(remainBalance == 0, User::getStatus, 2)
        .eq(User::getId, id)
        .eq(User::getBalance, user.getBalance())
        .update();

这种方式可以实现 SET 部分的动态拼接,非常适合复杂更新场景。


八、批量新增性能优化

1. saveBatch 原理分析

MyBatis-Plus 的 saveBatch 本质是 PreparedStatement 批量执行 ,但默认情况下,数据库仍会执行多条 INSERT 语句。

2. MySQL 批处理 SQL 合并优化

通过开启 MySQL 驱动参数:

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true

即可将多条 INSERT 合并为一条多值 SQL:

sql 复制代码
INSERT INTO user (...) VALUES (...), (...), (...);

开启后,批量插入性能可获得数量级提升。


九、总结

MyBatis-Plus 在传统 MyBatis 的基础上,提供了:

  • 强大的条件构造器(Wrapper / LambdaWrapper)
  • 通用 Service 层封装,减少模板代码
  • Wrapper + 自定义 SQL 的灵活扩展能力
  • lambdaQuery / lambdaUpdate 简化复杂业务逻辑
  • 批量操作的性能优化手段

在实际项目中,合理使用 Wrapper + Service 封装 + 批量优化参数,可以显著提升开发效率与系统性能,是企业级项目中非常值得掌握的一套技术方案。

相关推荐
爬山算法2 小时前
Hibernate(65)如何在微服务架构中使用Hibernate?
微服务·架构·hibernate
lbb 小魔仙5 小时前
【Java】Spring Cloud 微服务系统搭建:核心组件 + 实战项目,一步到位
java·spring cloud·微服务
loading小马7 小时前
Mybatis-Plus超级实用的多种功能用法
java·spring boot·后端·maven·mybatis
Miracle&8 小时前
微服务与高并发
微服务
indexsunny8 小时前
互联网大厂Java求职面试实录:Spring Boot微服务在电商场景中的应用及技术深度解析
java·数据库·spring boot·缓存·微服务·面试·电商
仙俊红8 小时前
Spring Cloud 核心组件部署方式速查表
后端·spring·spring cloud
计算机毕业设计开发9 小时前
django高校公寓管理系统--附源码64226
java·c++·spring boot·python·spring cloud·django·php
高山上有一只小老虎10 小时前
mybatisplus分页查询版本 3.5.8 以下和版本 3.5.9及以上的区别
java·spring boot·mybatis
人道领域10 小时前
javaWeb从入门到进阶(MyBatis拓展)
java·tomcat·mybatis