用了3年 MyBatis Plus,从"真香"到"真坑",这篇文章说点大实话。

一、先说好的:为什么这么多人用?

MyBatis Plus(简称 MP)在国内 Java 圈可以说是"国民级"ORM 框架了。它到底香在哪?

1. 代码生成器:CRUD 开发者的福音

自动生成 Controller、Service、Mapper、XML,项目启动时 80% 的基础代码不用手写。

2. 链式查询:优雅是真的优雅

不用写 SQL,类型安全,IDE 自动提示,代码洁癖患者狂喜。

3. 分页插件:开箱即用

几行配置,分页功能就有了,count 查询自动帮你做。

二、但是...坑来了

便利性的背后,有些坑你不踩不知道,踩了想跑路。

坑 1:隐式查询的"惊喜"

MP 的 selectById、selectOne 看着简单,但很多人不知道它默认会查出所有字段。如果你的 User 表有 50 个字段,但你只需要 name 和 phone,实际执行的是 SELECT * FROM user WHERE id = 1,这会导致网络 IO 暴涨、内存占用飙升。

正确姿势:使用 wrapper.select() 指定需要的字段。

坑 2:自动填充的"魔法"让人迷惑

看起来很方便,插入时自动填充时间。但问题是:批量插入时失效(saveBatch() 不会触发自动填充)、自定义 SQL 不走拦截器、更新时字段冲突。

坑 3:分页插件的性能陷阱

Count 查询慢到怀疑人生:复杂查询时,MP 自动生成的 count SQL 可能是子查询,数据量一大直接卡死。深分页性能断崖:MySQL 的深分页问题 MP 帮你解决不了。

坑 4:Wrapper 的链式调用是个"甜蜜陷阱"

调试困难:最终生成的 SQL 是啥?只能在日志里找。维护噩梦:三个月后回来看这段代码,想改不敢改。

坑 5:乐观锁的"假锁"

只支持单条更新,updateBatchById() 可能失效。并发高时大量冲突,没有重试机制。

坑 6:逻辑删除的"坑中坑"

唯一索引失效:用户删除后又注册,手机号冲突!关联查询的坑:你想查所有订单,但 MP 自动给所有查询加上 deleted=0。批量操作不走逻辑删除。

坑 7:TypeHandler 的"灵异事件"

某些场景反序列化失败,数据库里是字符串,Java 里是对象,类型转换隐藏 bug,批量操作时 Handler 不生效。

坑 8:批量操作的"死亡循环"(重点!)

这是生产环境最常见的性能杀手!

错误示范:循环单条插入

for (User user : userList) { userMapper.insert(user); }

假设插入 1万条数据:循环单条约 30-60 秒,真正的批量插入约 1-3 秒,差 10-30 倍!

你以为用了 MP 的 saveBatch 就没事了?

实际上还是拼接成多组 INSERT,不是真正的 JDBC Batch。数据量大时 SQL 过长,可能导致 MySQL max_allowed_packet 超限。

血泪教训:某电商平台大促期间,订单导入功能用了循环单条插入,1万条订单插入用了 2 分钟,接口超时,用户疯狂重试,数据库连接池被打满,整个系统雪崩。

三、效率问题:这才是最要命的

批量操作的效率真相

这是最容易被忽视的性能黑洞:

• for循环单条插入 1万条:30-60秒,10万条:直接超时

• MP saveBatch 1万条:3-5秒,10万条:30-50秒

• JDBC原生Batch 1万条:1-2秒,10万条:5-10秒

为什么差距这么大?

for 循环单条的问题:每次 insert = 1次网络往返 + 1次 SQL 解析 + 1次事务日志写入。1万条 = 1万次网络 RTT,数据库连接被长时间占用,连接池耗尽。

MP saveBatch 的问题:底层是拼接 INSERT INTO ... VALUES 语句,虽然减少了网络往返,但依然要解析执行多条 SQL。

JDBC Batch 的优势:真正的批量协议,一次网络发送多条数据,数据库端批量执行,减少解析开销。

四、那还该不该用?

我的建议:

✅ 小项目、快速原型 —— 用,效率第一

✅ 管理后台、CRUD 为主 —— 用,省心省力

❌ 核心交易系统 —— 慎用,考虑 MyBatis 或 JPA

❌ 复杂报表、大数据量 —— 自己写 SQL

❌ 追求极致性能 —— 不用,原生 MyBatis 更可控

使用建议:

1. 简单查询用 MP:省代码,提效率

2. 复杂查询手写 SQL:可控、可优化

3. 关键路径做性能测试:别等上线才发现问题

4. 定期 review 生成的 SQL:MP 不是银弹

五、写在最后

MyBatis Plus 是个好东西,它确实帮我们省了很多代码。但工具终究是工具,不要为了省事而省事。

记住:

• 框架带来的便利,是有代价的

• 黑盒操作越多,出问题时越难排查

• 性能问题往往藏在"省事的"代码里

用对地方,它是神器。用错地方,它是坑神。

你踩过 MyBatis Plus 的哪些坑?评论区聊聊

本文基于 MyBatis Plus 3.5.x 版本实践经验撰写