多数据源 ibatis.binding.BindingException Invalid bound statement

瑞星  金牌会员 | 2024-5-11 17:40:13 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 870|帖子 870|积分 2610

异常

本来 springboot 配置 mysql 配置正常,后来新加入了其他数据源,发现报错:
  1. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
复制代码
解决方案

多数据源配置下,解决 org.apache.ibatis.binding.BindingException Invalid bound statement (not found)问题
主要检查文件

1、检查mybatis.xml文件namespace名称是否和Mapper接口的全限定名是否一致
2、检查Mapper接口的方法在mybatis.xml中的每个语句的id是否一致
3、检查Mapper接口方法返回值是否匹配select元素配置的ResultMap,或者只配置ResultType
4、检查yml文件中的mapper的XML配置路径是否正确
5、Mybatis中接口与映射文件一定要同名或者必须在同一个包下,这个我没试过,好像是可以不同名的。
6、配置数据源的SqlSessionFactoryBean要使用MyBatisSqlSessionFactoryBean,这个也是鬼扯,MybatisPlus和Mybatis分清楚再说

7、编译没有把XML拷贝过来,可以用这招:
  1. <build>      
  2.     <resources>         
  3.         <resource>               
  4.             <directory>src/main/java</directory>               
  5.             <includes>                  
  6.                 <include>**/*.xml</include>            
  7.             </includes>
  8.         </resource>
  9.     </resources>
  10. </build>
复制代码
8、 启动会默认通过org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration * 类,我们是自定义的,所以需要排除MybatisAutoConfiguration
  1. @SpringBootApplication(exclude = MybatisAutoConfiguration.class)
复制代码
9、Mapper接口文件,不同数据源需要放置在不同包下面。
可能的原因都在这里了,各位慢用!!!
附上SqlSessionFactoryBean代码
ds1.java:
  1. package com.****.****.Configurer;
  2. import org.mybatis.spring.SqlSessionFactoryBean;
  3. import org.mybatis.spring.annotation.MapperScan;
  4. import org.springframework.beans.factory.annotation.Qualifier;
  5. import org.springframework.boot.context.properties.ConfigurationProperties;
  6. import org.springframework.boot.jdbc.DataSourceBuilder;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.context.annotation.Primary;
  10. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  11. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  12. import org.springframework.transaction.PlatformTransactionManager;
  13. import javax.sql.DataSource;
  14. @Configuration
  15. @MapperScan(basePackages = {"com.***.***.Mapper.ds1"}, sqlSessionFactoryRef = "ds1SqlSessionFactory")
  16. public class MybatisDS1Config {
  17.     @Bean(name = "ds1DataSource")
  18.     @ConfigurationProperties(prefix = "spring.datasource.ds1")
  19.     public DataSource dataSource() {
  20.         return DataSourceBuilder.create().build();
  21.     }
  22.     /**
  23.      * 配置事务管理器,不然事务不起作用
  24.      *
  25.      * @return
  26.      */
  27.     @Bean
  28.     public PlatformTransactionManager transactionManagerDS1() {
  29.         return new DataSourceTransactionManager(this.dataSource());
  30.     }
  31.     @Primary
  32.     @Bean(name = "ds1SqlSessionFactory")
  33.     public SqlSessionFactoryBean ds1sqlSessionFactory(@Qualifier("ds1DataSource") DataSource dataSource) throws Exception {
  34.         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  35.         sqlSessionFactoryBean.setDataSource(dataSource);
  36.         sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
  37.                 .getResources("classpath*:mapping/ds1/*.xml"));
  38.         sqlSessionFactoryBean.setTypeAliasesPackage("com.***.***.Entity");
  39.         sqlSessionFactoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
  40.         return sqlSessionFactoryBean;
  41.         /**
  42.          * 这里在applications.properties里面配置了
  43.          * mybatis.type-aliases-package=com.jwt.springboot.dao
  44.          * mybatis.mapper-locations=classpath:mapper/*Mapper.xml
  45.          * 但多数据源情况下执行sql总会报:org.apache.ibatis.binding.BindingException:
  46.          * Invalid bound statement (not found)........
  47.          * 原因是 this.mapperLocations 为null
  48.          *
  49.          * 注!!!!这里有大坑, 因为这里是自定义的sqlSessionFactoryBean,所以导致
  50.          * 没有启动时没有通过org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
  51.          * 类的sqlSessionFactory(DataSource dataSource)方法自动装配sqlSessionFactoryBean
  52.          * 自定义的sqlSessionFactoryBean所以也没设置mapperLocations
  53.          * 故自定义实例化sqlSessionFactoryBean这里需要手动设置mapperLocations
  54.          * 可参考:https://developer.aliyun.com/article/754124
  55.          */
  56.     }
  57. }
复制代码
ds2,java
  1. package com.***.***.Configurer;
  2. import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
  3. import org.apache.ibatis.session.SqlSessionFactory;
  4. import org.mybatis.spring.SqlSessionFactoryBean;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.boot.context.properties.ConfigurationProperties;
  8. import org.springframework.boot.jdbc.DataSourceBuilder;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.context.annotation.Configuration;
  11. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  12. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  13. import org.springframework.transaction.PlatformTransactionManager;
  14. import javax.sql.DataSource;
  15. @Configuration
  16. @MapperScan(basePackages = "com.***.***.Mapper.ds2", sqlSessionFactoryRef = "ds2SqlSessionFactory")
  17. public class MybatisDS2Config {
  18.     @Bean(name = "ds2DataSource")
  19.     @ConfigurationProperties(prefix = "spring.datasource.ds2")
  20.     public DataSource dataSource() {
  21.         return DataSourceBuilder.create().build();
  22.     }
  23.     /**
  24.      * 配置事务管理器,不然事务不起作用
  25.      *
  26.      * @return
  27.      */
  28.     @Bean
  29.     public PlatformTransactionManager transactionManagerDS2() {
  30.         return new DataSourceTransactionManager(this.dataSource());
  31.     }
  32.     @Bean("ds2SqlSessionFactory")
  33.     public SqlSessionFactory ds2sqlSessionFactory(@Qualifier("ds2DataSource") DataSource dataSource) throws Exception {
  34.         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  35.         sqlSessionFactoryBean.setDataSource(dataSource);
  36.         sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
  37.                 .getResources("classpath*:mapping/ds2/*.xml"));
  38.         sqlSessionFactoryBean.setTypeAliasesPackage("com.***.***.Entity");
  39.         sqlSessionFactoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
  40.         return sqlSessionFactoryBean.getObject();
  41.     }
  42. }
复制代码
yml配置:
  1. spring:
  2.   datasource:
  3.     ds1: #主数据库,生产数据库
  4.       username: ***
  5.       password: ***
  6.       #url中database为对应的数据库名称   //数据库名字
  7.       jdbc-url: jdbc:mysql://***:3306/crmdb?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
  8.       driver-class-name: com.mysql.cj.jdbc.Driver
  9.     ds2: #从数据库,分析数据库
  10.       username: ***
  11.       password: ***
  12.       #url中database为对应的数据库名称   //数据库名字
  13.       jdbc-url: jdbc:mysql://***:3306/jmsns?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
  14.       driver-class-name: com.mysql.cj.jdbc.Driver
复制代码
文件目录结构:

另外,在Linux环境下:
  1. new PathMatchingResourcePatternResolver().getResources("classpath*:mapping/ds2/*.xml"));
复制代码
可能出现找不到配置文件的问题,我用的替代方法是:
  1. new ClassPathResource[]{new ClassPathResource("/mapping/ds1/UserMapper.xml")}
复制代码
总结

添加数据源的时候,只测试新的数据源确实可以,但是影响了旧的功能。
所以一定要注意影响范围。
参考资料

多数据源配置下,解决 org.apache.ibatis.binding.BindingException Invalid bound statement (not found)问题
本文由博客一文多发平台 OpenWrite 发布!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

瑞星

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表