自定义SqlSessionFactoryBean导致 mapper-locations 失效
问题重现
步骤
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
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
设计模式-责任链模式
理解 责任链的执行序列是一环连着一环,后一环的执行依赖前一环的执行,层层递进. 流程图 组成部分 链条:负责承前启后; 链条上的环:执行业务逻辑,决定是否继续执行下一个环(有的情况由链条决定); 执行流: 前期:由外层到里层; 后期:由里层到外层 特点 链条上相邻的环之间会影响,影响入参和出参; 每个环负责相对独立的任务,比如有的负责字符编码设置,有的负责流的编码和解码(比如gzip),有的负责记录日志等 实例 一个简单的 demo 项目代码 链条类 public class DaoFilterChain { private List<IFilter> filterList = new ArrayList<>(); private int index = 0; private boolean hasAddDefaultFilter = false; public DaoFilterChain addFilter(IFilter filter) { if (hasAddDefaultFilter) { throw new RuntimeException("自定义...
- 下一篇
常用的软件技术思想-池化技术等
池化技术 实际案例今天去公司食堂吃早点,排了一队人,先是包子馒头,然后是韭菜盒子,各种饼,最后是喝的,比如小米粥,黑米粥,豆浆等,发现队伍阻塞在最后那一段(小米粥,黑米粥,豆浆)了,这个说要黑米粥,阿姨忙不迭地去打黑米粥,那个说要小米粥,阿姨赶紧去打小米粥。。。阿姨已经没有功夫来决定打哪个了。那么我们看看另外一种情况,阿姨提前做好囤货的工作,比如小米粥,黑米粥,豆浆各打10碗放着,谁要谁自己拿。阿姨的工作就不用围着顾客团团转了,而是看哪个少了,就打哪个,比如发现黑米粥还剩下3碗了,那么就多打黑米粥。 简单来说就是提前保存大量的资源,以备不时之需 核心是复用 池化技术作用 复用相同的资源,减少浪费,减少新建和销毁的成本; 减少单独管理的成本,统一交由"池"; 集中管理,减少"碎片"; 提高系统响应速度,因为池中有现成的资源,不用重新去创建; 使用池化技术的例子 java线程池 java中所有的池化技术都有一个好处,就是通过复用池中的对象,降低系统资源消耗。设想一下如果我们有n多个子任务需要执行,如果我们为每个子任务都创建一个执行线程,而创建线程的过程是需要一定的系统消耗的,最后肯定会拖慢...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装Docker,最新的服务器搭配容器使用
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7安装Docker,走上虚拟化容器引擎之路