MyBatis Mapper 扫描失败主因是 starter 版本不匹配、@MapperScan 路径错误或 XML 路径配置失效;Spring Boot 2.x 用 starter 2.x,3.x 用 3.x;@MapperScan 必须写完整包名且覆盖子包;XML 路径须以 classpath: 开头。

mybatis-spring-boot-starter 版本选错直接导致 Mapper 扫描失败
Spring Boot 2.x 和 3.x 对 mybatis-spring-boot-starter 的版本要求完全不同,用错就根本不会扫描 @Mapper 接口,连启动日志里都看不到 MyBatis 初始化痕迹。
- Spring Boot 2.7.x 及以下 → 用
mybatis-spring-boot-starter2.x(如2.3.1) - Spring Boot 3.0+ → 必须用
mybatis-spring-boot-starter3.x(如3.0.3),且底层依赖 Java 17+、Jakarta EE 9+ - 常见错误现象:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found),其实是 Mapper 根本没被注册进 Spring 容器 - 检查方式:启动后看日志是否出现
Registered mapper interface...,没有就是 starter 没生效
@MapperScan 注解路径写错或漏配,包下接口全被忽略
@MapperScan 是最常用也最容易翻车的配置点——它不认相对路径、不自动递归子包(除非显式声明)、还和组件扫描范围打架。
- 必须写完整包名,比如
@MapperScan("com.example.project.mapper"),不能写成mapper或./mapper - 子包默认不扫描,要覆盖
com.example.project.mapper.user和com.example.project.mapper.order,得写成@MapperScan("com.example.project.mapper.*")或分别列出 - 如果主启动类不在根包,
@MapperScan路径又写得比实际包浅,会导致“找不到任何 Mapper”;反过来写深了,会静默跳过 - 和
@SpringBootApplication(scanBasePackages = "...")冲突时,后者范围必须包含前者,否则@MapperScan无效
Mapper 接口加了 @Mapper 却没配 @MapperScan,结果只生效一个
@Mapper 是 MyBatis 的原生注解,不是 Spring 的 @Component,它只对**单个接口**起作用,且必须配合 mybatis-spring-boot-starter 的自动配置才能被识别。
- 每个接口都加
@Mapper能绕过@MapperScan,但非常脆弱:一旦忘了加,运行时报BeanCreationException: No qualifying bean of type 'XxxMapper' - IDE 可能不提示缺失
@Mapper,因为编译无错;但 Spring 启动时不报错,只是该 Mapper 不可用 - 在模块化项目(多 module)中,
@Mapper只在当前 module 生效,跨 module 的接口必须靠@MapperScan扫描,否则找不到 - 推荐做法:统一用
@MapperScan,只在测试或临时调试时用@Mapper
application.yml 里 mybatis.mapper-locations 配置错位置,XML 文件压根不加载
如果你用 XML 方式写 SQL,mybatis.mapper-locations 写错路径或格式,MyBatis 就当那些 XML 不存在,但也不会报错,只会 fallback 到注解 SQL 或抛出空映射异常。
- 路径是 classpath 相对路径,必须以
classpath:开头,比如classpath:mapper/*.xml;写成src/main/resources/mapper/或mappers/都无效 - 多个路径用逗号分隔,不要换行或空格,例如
classpath:mapper/user.xml,classpath:mapper/order.xml - 注意文件名大小写:Windows 下可能不敏感,Linux/CI 环境下
UserMapper.xml和usermapper.xml是两个文件 - 验证方法:启动后检查
org.apache.ibatis.session.Configuration是否包含你定义的MappedStatement,或者 debug 时看SqlSessionFactoryBean的mapperLocations属性是否解析出实际资源
Spring Boot 集成 MyBatis 最容易卡住的地方,从来不是语法,而是「配置生效了没」——starter 版本、包路径、资源路径这三处,任意一个字符不对,就会静默失效。别猜,启动时盯紧日志里那几行 Registered mapper interface 和 Loading XML mapper files。










