Mapper XML已经出现在target目录,调用仍报 Invalid bound statement,不能就此排除配置问题。文件被打包、资源被加载、statement被注册,是三个不同阶段。
这次最后发现的是前缀拼错
2019年整合Spring Boot和MyBatis时,调用DAO报:
Invalid bound statement (not found): com.dao.DeptDao.findAll
我检查过输出目录,XML确实存在;继续调试加载过程,发现映射内容没有读进去。最后逐项核对application.yml,才找到 mybatis 前缀拼写错误,下面的mapper-locations没有按预期绑定。改正后,当时的问题解决。
这是一种具体原因,不是该错误的唯一解释。
对照一个明确的最小映射关系
使用普通MyBatis Spring Boot Starter,假设接口叫 example.mapper.DeptMapper:
package example.mapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface DeptMapper {
List<Map<String, Object>> findAll();
}
对应XML放到约定资源目录,namespace与接口全名、id与方法名一致:
<mapper namespace="example.mapper.DeptMapper">
<select id="findAll" resultType="map">
SELECT id, name FROM demo_department
</select>
</mapper>
相关YAML示例:
mybatis:
mapper-locations: classpath*:/mapper/**/*.xml
这里的表需要测试工程实际提供;示例只说明契约,不是即插即用数据库应用。使用MyBatis-Plus时要查对应的 mybatis-plus 配置体系;多个SqlSessionFactory或自定义配置时,也可能绕过默认加载逻辑。MyBatis Starter配置
按加载链条找,不只盯着target
依次检查当前profile与最终生效配置、资源匹配表达式、实际运行的JAR内容、XML解析错误、namespace/id和Mapper绑定的工厂。IDE输出目录存在某文件,不保证部署包中也有;Java接口已扫描,也不代表XML语句已注册。
若实际路径是 /mappers/ 而非 /mapper/,就按实际布局修改,不能机械照抄示例。
诊断日志按Mapper范围临时开启
另一条2018年笔记通过Mapper包名打开日志。properties形式:
logging.level.example.mapper=DEBUG
YAML形式:
logging:
level:
example.mapper: DEBUG
包名不固定,也不必把每个点拆成一层。还要确认MyBatis实际选择的日志实现与应用的输出配置一致。MyBatis日志说明
SQL及参数可能包含用户资料,只在必要范围和时间内诊断,避免长期记录敏感输入。日志是观察手段,不会替你注册缺失的statement。