MyBatis-Plus 不支持自定义注解生成通用 SQL,推荐通过 SQL 注入器 + 方法命名约定 + BaseMapper 继承实现;核心是定义 AbstractMethod 子类、自定义 SqlInjector 并替换默认注入器,从而全局注入如 selectListFromMaster 等方法。

MyBatis-Plus 本身不支持“自定义注解”直接生成通用 SQL(比如 @SelectFromMaster 或 @BatchUpdate 这类新注解),它只识别内置的 MyBatis 注解(如 @Select、@Update、@Insert、@Delete)和 MP 自带的扩展机制(如 SQL 注入器)。所谓“在 Mapper 接口方法上扩展通用 SQL”,真正可行且推荐的方式是:**不造新注解,而是通过 SQL 注入器 + 方法命名约定 + BaseMapper 继承来实现语义化、复用性强的通用方法**。
用 SQL 注入器注入通用方法(推荐主路径)
这是 MP 官方支持、生产环境验证过的标准扩展方式,能真正实现“一次定义、全局可用、类型安全”。核心是三步:
- 定义一个继承
AbstractMethod的类,负责拼 SQL 并组装成MappedStatement - 编写自定义
SqlInjector,把上面的方法注册进去 - 在配置类中将自定义注入器替换掉默认的
MybatisPlusAutoConfiguration注入器
例如,添加一个「从主库查询列表」方法 selectListFromMaster:
- 定义枚举
SqlMethodEx.MASTER_SELECT_LIST,指定方法名、描述和 SQL 模板(含主库路由前缀) - 写
SelectListFromMasterMethod extends AbstractMethod,在injectMappedStatement中调用sqlSource = languageDriver.createSqlSource(...)构建脚本 - 自定义
CustomSqlInjector extends DefaultSqlInjector,重写getMethodList,返回新增的 method 实例 - 配置类中
@Bean返回该注入器,MP 启动时自动扫描所有继承BaseMapper的接口,并为每个 mapper 注入selectListFromMaster方法
在 Mapper 接口用 @Select/@Update 等注解写定制 SQL(适合单点需求)
如果只是某个业务场景临时需要一条特殊 SQL,无需全局复用,直接在 Mapper 接口方法上加 MyBatis 原生注解最轻量:
立即学习“Java免费学习笔记(深入)”;
@Select("SELECT * FROM user WHERE status = #{status} AND create_time >= #{startTime}")@Update("UPDATE user SET status = #{status} WHERE id IN <foreach item="id" collection="ids" open="(" separator="," close=")">#{id}</foreach>")- 参数必须用
@Param显式命名(尤其多参数时),否则运行时报BindingException - SQL 中可安全使用
#{}防注入;需动态表名/列名时才用${}(务必校验来源,避免 SQL 注入)
继承自定义 BaseMapper 接口(适合团队规范统一)
若多个模块都需要一组固定扩展方法(如 selectByStatus、deleteLogicBatch),可定义公共父接口:
- 新建
CommonBaseMapper<T>,继承BaseMapper<T>,再声明若干@Select/@Update方法 - 各业务 Mapper(如
UserMapper)统一继承CommonBaseMapper<User> - 优点:无侵入、易理解、便于 IDE 跳转;缺点:每个方法仍是静态 SQL,无法跨实体复用逻辑(比如不能让
selectByStatus自动适配不同表的 status 字段名)
不建议走的路:自己解析自定义注解
有人尝试定义 @MasterQuery 注解,再写 @Aspect 切面或 Interceptor 拦截方法调用并改写 SQL。这条路问题明显:
- 绕过 MP 的 MappedStatement 注册机制,丢失缓存、插件链(分页、性能分析等)、参数绑定等核心能力
- 无法与 MP 的
Wrapper、Page等对象自然融合 - 维护成本高,容易和 MP 升级冲突
真正需要“注解式语义”的场景,应优先回归 SQL 注入器方案——它本质就是 MP 为你预留的、官方认可的“注解扩展接口”。


















