問題重制
步驟
1,把所有的mapper xml移動到 /xxx/yyy/src/main/resources/mybatis/mapperxml 中;
2,修改application.properties ,添加:
mybatis.mapper-locations=classpath:**/mapperxml/*.xml
3,啟動springboot 程式 com/test/xxx/app/nnn/Application.java
4,通路接口
http://127.0.0.1:/nnn/productManage/listYYs.json?ccKey=Key222&vvName=%AF%B7%E5%81%87App報錯:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
初步分析
根據現象推斷出,spring boot 沒有讀取我的 mybatis mapper xml檔案

是以需要找出來,讀取mybatis mapper xml檔案 的邏輯在哪裡,為什麼沒有讀取?
定位問題過程
讀取mapper xml檔案 的邏輯/位置
/repository/org/mybatis/mybatis-spring/1.3.2/mybatis-spring-1.3.2-sources.jar!/org/mybatis/spring/SqlSessionFactoryBean.java的
protected SqlSessionFactory buildSqlSessionFactory() throws IOException 方法中
讀取mapper xml檔案的邏輯
if (!isEmpty(this.mapperLocations)) {
for (Resource mapperLocation : this.mapperLocations) {
if (mapperLocation == null) {
continue;
}
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
configuration, mapperLocation.toString(), configuration.getSqlFragments());
xmlMapperBuilder.parse();
}
} else {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Property 'mapperLocations' was not specified or no matching resources found");
}
}
通過IDEA 調試到這兒的時候,發現 this.mapperLocations 為null,是以才沒有走這個邏輯
為什麼this.mapperLocations 為null
this.mapperLocations 是在哪裡設定的呢?
在 org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 類中,
sqlSessionFactory(DataSource dataSource)
設定this.mapperLocations的代碼:
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
factory.setMapperLocations(this.properties.resolveMapperLocations());
}
之是以沒有執行MybatisAutoConfiguration 中的 sqlSessionFactory(DataSource dataSource) throws Exception 方法,是因為
SqlSessionFactoryBean
是我們定制的,沒有依賴系統生成.
我們自定義生成SqlSessionFactoryBean 對象
final SqlSessionFactoBean sessionFactoryBean = new SqlSessionFactoBean();
sessionFactoryBean.setDataSource(aaaGroupDataSource);
SqlSessionFactory sqlSessionFactory = sessionFactoryBean.getObject();
// mybatis自動通用字段自動設定配置
org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();
return sqlSessionFactory;
系統構造SqlSessionFactory
在/repository/org/mybatis/mybatis-spring/1.3.6/mybatis-spring-1.3.6-sources.jar!/org/mybatis/spring/SqlSessionFactoryBean.java 的
protected SqlSessionFactory buildSqlSessionFactory() throws IOException
原因總結
因為我們自定義生成 SqlSessionFactoryBean對象 導緻沒有執行org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 類的sqlSessionFactory(DataSource dataSource)方法
解決方法
手動添加設定this.mapperLocations 的邏輯即可:
final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
//解決 application.properties 中 配置mybatis.mapper-locations 失效的問題
if (!ObjectUtils.isEmpty(this.mybatisProperties.resolveMapperLocations())) {
sessionFactoryBean.setMapperLocations(this.mybatisProperties.resolveMapperLocations());
}
sessionFactoryBean.setDataSource(aaaGroupDataSource);
SqlSessionFactory sqlSessionFactory = sessionFactoryBean.getObject();
// mybatis自動通用字段自動設定配置
org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();
// 。。。
return sqlSessionFactory;
//解決 application.properties 中 配置mybatis.mapper-locations 失效的問題
<span data-type="color" style="color:#F5222D">if (!ObjectUtils.isEmpty(this.mybatisProperties.resolveMapperLocations())) {</span>
sessionFactoryBean.setMapperLocations(this.mybatisProperties.resolveMapperLocations());
}
tips
若想親自調試,可以關注如下類:
- org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
- org.mybatis.spring.SqlSessionFactoryBean
- org.apache.ibatis.session.SqlSessionFactoryBuilder