MyBatis Plus 的实用技巧:从业务场景到代码实现

MyBatis Plus 的实用技巧:从业务场景到代码实现

作者:Java 工程师 / 架构师

年限:8 年 Java 后端开发经验,专注于企业级系统架构与中台设计。


一、前言

作为一名有多年 Java 后端开发经验的工程师,我经历了从原始 JDBC 到 Hibernate,再到 MyBatis 的演进。而在 MyBatis 的基础上,MyBatis Plus(MP) 的出现无疑大大提升了我们的开发效率,尤其是在中后台管理系统、BFF 层接口、快速迭代项目中表现尤为突出。

本文将基于几个真实的业务场景,分享我在使用 MyBatis Plus 过程中的一些实用技巧,包括查询优化、批量操作、代码规范、分页、分表等内容,结合代码进行逐一解析。


二、业务场景一:动态查询构建太复杂?

背景

在实际业务中,如订单查询接口,前端会传递多个条件:订单号、客户名、下单时间范围、状态等。传统 MyBatis 里 XML 动态 SQL 写起来冗长、难维护、易出错。

解决方案:使用 QueryWrapper 构建动态查询条件

less 复制代码
QueryWrapper<Order> wrapper = new QueryWrapper<>();
wrapper.eq(StringUtils.isNotBlank(query.getOrderNo()), "order_no", query.getOrderNo())
       .like(StringUtils.isNotBlank(query.getCustomerName()), "customer_name", query.getCustomerName())
       .ge(query.getStartTime() != null, "create_time", query.getStartTime())
       .le(query.getEndTime() != null, "create_time", query.getEndTime())
       .eq(query.getStatus() != null, "status", query.getStatus());

优点

  • 代码更清晰,条件判断集中处理
  • 避免 XML 动态 SQL 的拼写错误
  • 易于维护和扩展

三、业务场景二:分页查询性能瓶颈

背景

在订单列表分页接口中,记录数过大,导致分页查询性能下降。

解决方案:

  1. 使用 MP 的分页插件
  2. 优化 SQL:避免 select *,只查必要字段
  3. 索引优化

示例代码:

ini 复制代码
Page<Order> page = new Page<>(query.getPageNo(), query.getPageSize());
IPage<OrderVO> result = orderMapper.selectPage(page, wrapper);

配置分页插件(Spring Boot):

java 复制代码
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    return interceptor;
}

四、业务场景三:批量插入/更新操作写起来繁琐?

背景

在导入 Excel 表时,需要将上千条记录导入数据库。传统做法是循环执行 insertupdate 操作,效率极低。

解决方案:使用 MP 提供的批量操作方法

scss 复制代码
// 批量插入
orderService.saveBatch(orderList);

// 批量更新
orderService.updateBatchById(orderList);

注意事项

  • 默认每 1000 条提交一次,可以通过 saveBatch(list, batchSize) 设置
  • 批量更新时需确保实体类包含主键

五、业务场景四:逻辑删除支持不一致?

背景

部分表支持逻辑删除(is_deleted 字段),部分表不支持。在查询时容易忘记加上 is_deleted = 0 条件。

解决方案:使用 MP 的逻辑删除插件

配置实体类:

java 复制代码
@TableLogic
private Integer isDeleted;

全局配置:

yaml 复制代码
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: isDeleted
      logic-delete-value: 1
      logic-not-delete-value: 0

效果

MP 会自动在删除、查询时加上逻辑删除条件,无需手动维护。


六、业务场景五:多表查询怎么办?

背景

MyBatis Plus 不支持多表关联查询,但实际业务中又常常需要查询用户和订单的联表信息。

解决方案:使用自定义 SQL

less 复制代码
@Select("SELECT o.*, u.name AS user_name FROM orders o JOIN users u ON o.user_id = u.id WHERE o.status = #{status}")
List<OrderDTO> selectOrderWithUserName(@Param("status") Integer status);

或使用 BaseMapper.xml 和 DTO 映射结合使用。

小技巧:

  • 尽量将复杂 SQL 拆分成多个 VO/DTO 查询
  • 不推荐使用 MP 做过于复杂的联表逻辑,保持职责清晰

七、总结与最佳实践

场景 技巧 工具/方法
多条件查询 动态 QueryWrapper eq/like/ge/le
分页优化 分页插件 + 索引 selectPage()
批量操作 saveBatch / updateBatchById 自动分批提交
逻辑删除 注解 + 全局配置 @TableLogic
多表查询 自定义 SQL + DTO @Select + 手动映射

最佳实践建议:

  • 统一封装 Wrapper 构建器:减少重复代码
  • 合理使用 BaseMapper,自定义复杂 SQL 放到 Mapper.xml
  • 注重 SQL 语句的性能优化,避免 ORM 成为瓶颈
  • 配合 Lombok、MapStruct 提高开发效率

八、结语

MyBatis Plus 是一把好刀,用得好可以显著提升开发效率;但也要注意它的边界与短板。作为一名有多年开发经验的工程师,我们更应关注其背后的思想:如何通过规范化、组件化、工具化的方式提升系统的可维护性和开发效率。

希望本文对你在使用 MyBatis Plus 的过程中有所启发,欢迎留言交流更多实战经验!

相关推荐
Luke Ewin10 小时前
FunASR的Java实现Paraformer实时语音识别 | 一款无需联网的本地实时字幕软件
java·人工智能·语音识别·asr·funasr·paraformer·sensevoice
叫我阿柒啊10 小时前
从Java全栈到前端框架的全面实战:一次真实面试的深度解析
java·spring boot·缓存·微服务·消息队列·vue3·rest api
望未来无悔10 小时前
系统学习算法 专题十八 队列+宽搜
java·算法
一只叫煤球的猫10 小时前
2025年基于Java21的的秒杀系统要怎么设计?来点干货
后端·面试·性能优化
Linlichaoblms11 小时前
Nginx性能调优:参数详解与压测对比
java·spring boot·nginx
方圆想当图灵11 小时前
《生产微服务》评估清单 CheckList
后端·微服务
服务端技术栈11 小时前
历时 1 个多月,我的第一个微信小程序「图片转 Excel」终于上线了!
前端·后端·微信小程序
一个很老的小萌新11 小时前
json 解析 [{“id“:1,“name“:“apple“},{“id“:2,“name“:“banana“}]
java·前端·json
计算机毕业设计指导11 小时前
基于Spring Boot的幼儿园管理系统
spring boot·后端·信息可视化
是2的10次方啊11 小时前
🏗️ 线程池深度解析:ThreadPoolExecutor底层实现与CompletableFuture异步编程实战
java