MyBatis-Plus是基于MyBatis的增强工具包,不替代MyBatis,所有SQL仍由原生MyBatis执行;它仅在接口层和条件构造器上增强,通过继承BaseMapper提供通用CRUD方法,且与PageHelper等插件无缝兼容。

MyBatis-Plus 是什么,和 MyBatis 什么关系
MyBatis-Plus 不是替代 MyBatis 的新框架,而是直接基于 MyBatis 的增强工具包。它不碰 SqlSessionFactory、MapperScannerConfigurer 这些核心机制,所有 SQL 执行流程完全走原生 MyBatis 路径,只是在你写 DAO 层时,帮你省掉大量模板代码。
关键判断:如果你项目里已经用着 MyBatis,加个依赖、扫个包、继承 BaseMapper,就能立刻用上 selectById、updateById 这类方法——不需要改 XML,也不需要动 SqlSession 调用逻辑。
为什么说“只做增强不做改变”不是宣传话术
它真没动 MyBatis 的底层契约。比如:
-
Configuration对象照常初始化,MapperRegistry依然注册你的接口,连MapperProxy都没重写 - 所有自动生成的 SQL(如
selectList对应的 SELECT)最终还是交给DefaultSqlSession执行,日志里看到的依然是标准 MyBatis 的 SQL 日志格式 - 你手写的
@Select("...")或 XML 中的<select>标签,优先级永远高于 MP 的自动 SQL,冲突时 MP 主动退让
换句话说:MP 的增强全在“接口层”和“条件构造器”上,执行层完全透明。这也是它能和分页插件(如 PageHelper)、多数据源(如 dynamic-datasource)无缝共存的原因。
容易踩的坑:自动填充、逻辑删除、乐观锁这些功能怎么生效
这些不是开箱即用的魔法,必须显式配置,否则完全不触发:
- 自动填充字段(如
create_time)要实现MetaObjectHandler接口,并在 Spring Boot 中声明为@Bean,否则TableField(fill = FieldFill.INSERT)白标 - 逻辑删除需要在实体类字段上加
@TableLogic,同时在application.yml里配mybatis-plus.global-config.db-config.logic-delete-field和对应值(如deleted),缺一不可 - 乐观锁要用
@Version注解字段,且必须全局开启插件:MybatisPlusConfig里加new OptimisticLockerInterceptor(),否则updateById永远不带WHERE version = ?
这些功能都依赖 MP 的 InnerInterceptor 机制,在 SQL 构建阶段注入逻辑——不是靠 AOP 或代理拦截,所以配置漏了就真的没反应,也不会报错。
什么时候不该用 MyBatis-Plus
它擅长 CRUD 均衡、结构清晰的业务表,但遇到这几类场景就得收手,老实用原生 MyBatis:
- 复杂联查(如五张表 JOIN + 子查询嵌套),
QueryWrapper写出来语义模糊,SQL 可读性暴跌,不如直接写 XML - 动态 SQL 极度频繁(比如 WHERE 条件组合有十几种分支),
QueryWrapper.lambda()链式调用容易变成“俄罗斯套娃”,维护成本反超 XML - 需要精细控制一级/二级缓存策略,或深度定制
ResultSetHandler行为,MP 的封装层反而成了障碍
最典型的信号是:你发现自己在反复调用 queryWrapper.and() 拼条件,却越来越难看清最终 SQL 长什么样——这时候就该切回 @SelectProvider 或 XML 了。










