namespace必须与接口全限定名完全一致,如com.example.mapper.usermapper,否则mybatis无法绑定xml与接口,导致getmapper()返回null或抛bindingexception。

namespace 必须和接口全限定名完全一致
MyBatis 靠 namespace 把 XML 文件和 Java 接口“对上号”,不是靠文件名、路径或方法名。如果写错,哪怕只差一个字母或大小写,SqlSession.getMapper() 就会返回 null,或者执行时抛 BindingException: Invalid bound statement。
-
namespace值必须是接口的完整类名(含包路径),例如com.example.mapper.UserMapper,不能写成UserMapper或mapper.UserMapper - 接口里有默认方法(default method)或静态方法,XML 里也不能定义同名
<select></select>标签——MyBatis 只绑定 public abstract 方法 - 如果接口在 module-info.java 中被导出,但 XML 在另一个模块,需确保资源路径可被
ClassLoader加载到,否则namespace对得上也找不到语句
XML 里的 id 不是独立标识,而是 namespace + id 的组合键
单看 id="selectById" 没意义,真正唯一标识一条 SQL 语句的是 com.example.mapper.UserMapper.selectById。这也是为什么不同 namespace 下可以重用相同 id,而同一 namespace 内重复 id 会导致后加载的覆盖前一个。
- 调用
sqlSession.selectOne("com.example.mapper.UserMapper.selectById", 123)时,字符串里必须带全 namespace;用接口方式调用则由 MyBatis 自动拼接 - IDE(如 IntelliJ)能跳转到对应 XML 方法,依赖的就是这个组合规则;如果 namespace 错了,跳转会失效,但不会报错,容易误以为“功能正常”
- 动态 SQL 中引用其他语句(如
<include refid="commonColumns"></include>)不走 namespace 查找,refid是局部作用域,和 namespace 无关
接口继承时 namespace 不能共享,子接口必须单独配 XML
Java 接口支持多层继承,但 MyBatis 不支持“复用父接口的 namespace”。哪怕 UserMapper extends BaseMapper<user></user>,XML 的 namespace 仍必须写 com.example.mapper.UserMapper,不能写父接口名。
- 父接口的 XML(如
BaseMapper.xml)即使存在且namespace="com.example.mapper.BaseMapper",也不会被子接口自动继承或合并 - 如果多个子接口共用一套通用 SQL,只能复制粘贴,或改用
<sql></sql>片段 +<include></include>,片段定义在哪个 XML 里,就只在那个 namespace 下可见 - 使用
@Mapper注解的接口,若没配 XML,MyBatis 会尝试用注解方式(@Select等)生成语句;此时不存在 namespace 绑定问题,但一旦加了同名 XML,就必须严格匹配
namespace 写错时,错误表现往往延迟且模糊
最麻烦的不是直接报错,而是静默失败:SQL 执行了,结果为空、字段为 null、甚至查到别的表数据——因为 MyBatis 找不到对应语句,可能 fallback 到缓存、代理对象默认行为,或意外匹配到其他 namespace 的同名 id。
- 开启
log4j.logger.org.apache.ibatis=DEBUG后,启动日志里会打印 “Mapped Statements” 列表,确认你写的namespace.id是否出现在其中 - 单元测试里用
sqlSession.getConfiguration().getMappedStatement("xxx")主动查一下,比等运行时报错更早发现问题 - Spring Boot 项目中,如果用了
mybatis.mapper-locations配置但路径写错(比如漏了classpath*:),XML 根本没被加载,namespace 就是无效的——此时连 DEBUG 日志里都看不到那条语句
namespace 表面上只是个字符串,实际是 MyBatis 运行时解析、缓存、代理三者协同的锚点。写错它,问题可能藏在任意一层,而且不报错。










