美文网首页
Spring Boot多数据源Mybatis配置爬坑记录

Spring Boot多数据源Mybatis配置爬坑记录

作者: tenlee | 来源:发表于2017-09-22 15:15 被阅读2897次

    开始配置

    application.properties大致如下:

    spring.datasource.url=jdbc:mysql://localhost:3306/demo
    spring.datasource.username=root
    spring.datasource.password=root
    
    
    spring.datasource.two.url=jdbc:mysql://localhost:3306/demo2
    spring.datasource.two.username=root
    spring.datasource.two.password=root
    

    DefaultConfig.java 如下:

    package com.demo
    
    import ...
    
    @Configuration
    @MapperScan(basePackages = {"com.demo.**.mapper"})
    @EnableTransactionManagement(proxyTargetClass = true)
    public class DefaultConfig {
    @Bean
        @ConfigurationProperties("spring.datasource.druid")
        @Primary
        public DataSource dataSource() {
            DataSource dataSource = DruidDataSourceBuilder.create().build();
            return dataSource;
        }
    
        @Bean
        @Primary
        public DataSourceTransactionManager dataSourceTransactionManager() {
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(dataSource());
            return dataSourceTransactionManager;
        }
    
        @Bean
        @Primary
        public SqlSessionFactory sqlSessionFactory() throws Exception {
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(dataSource());
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                                                  .getResources("classpath*:config/mapper/*.xml"));
            return sessionFactory.getObject();
        }
    }
    

    第二个数据源Mybatis配置
    AdaptorConfig.java如下:

    @Configuration
    @MapperScan(value = "com.demo.adaptor.mapper",
        sqlSessionFactoryRef = AcAppAdaptorConfig.SQL_SESSION_FACTORY)
    @EnableTransactionManagement(proxyTargetClass = true)
    public class AdaptorConfig {
    
        public static final String SQL_SESSION_FACTORY = "mybatisSqlSessionFactoryAdaptor";
    
        // ac-adaptor
        @Bean
        @ConfigurationProperties("spring.datasource.two")
        public DataSource dataSourceAdaptor() {
            DataSource dataSource = DruidDataSourceBuilder.create().build();
            return dataSource;
        }
    
        @Bean
        public DataSourceTransactionManager txManagerApp() {
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(dataSourceAdaptor());
            return dataSourceTransactionManager;
        }
    
        @Bean(name = AcAppAdaptorConfig.SQL_SESSION_FACTORY)
        public SqlSessionFactory mybatisSqlSessionFactoryAdaptor() throws Exception {
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(dataSourceAdaptor());
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                                                  .getResources(
                                                      "classpath*:config/mapper/com/petkit/adaptor/mapper/*.xml"));
            return sessionFactory.getObject();
        }
    }
    

    注意,第二个数据源的 @MapperScan 必须显示指定 sqlSessionFactory 的bean name,否则使用默认的 sqlSessionFactory,如果 sqlSessionFactory 使用错误,那么会导致xml和mapper接口就会对应不上,出现
    No MyBatis mapper was found in...或者
    handle Exception : Invalid bound statement (not found):的错误

    1. 配置完成,跑一下看看,果然没错,正常运行,配置成功了
    2. 然后,由Jenkins 打包,部署到服务器之后,居然出错了,错误如下
      handle Exception : Invalid bound statement (not found):
      ,难道是Jenkins的缓存,没更新xml文件,导致没找到xml文件而无法绑定?因为本地运行正常啊。。。
    3. 登录jenkins服务器,发现代码都是最新的,一切都是正常的。
      那就应该是 sqlSessionFactory 没有正确注入到com.demo.adaptor.mapper包里面,从而导致mapper接口没有找到xml文件。
    4. 分析发现,由于两个 @MapperScan的扫描路径有重复,且DefaultConfig的MapperScan包括了AdaptorConfig的MapperScan,Spring boot 读取 @Configuration进行配置的时候是无序的,并不能保证AdaptorConfig里面的配置先于DefaultConfig执行,导致com.demo.adaptor.mapper的mapper接口sqlSessionFactory里面的MapperLocations对应,而不是期望的mybatisSqlSessionFactoryAdaptor。(
      但是我本地的Springboot是按照class名字母顺序进行配置的,所以才导致AdaptorConfigDefaultConfig先执行先注入,所以本地一直是运行成的。)

    解决问题

    1. 使用@Order, 即在DefaultConfig.java同时加上@Order注解,实验之后,并没有作用。
    2. 使用@Import, 即在DefaultConfig.java加上@Import(AdaptorConfig.class), 可用,但是需要去掉AdaptorConfig.java上的@Configuration注解,但是在运行时,发现AdaptorConfig.java里面的DataSource属性未注入,是null。解决方案是将dataSourceAdaptor放到在DefaultConfig.java中,可行。缺点就是没有做到模块分离。
    3. 修改package名,使两个MapperScan扫描不重复即可。缺点就是命名不够规范了。

    相关文章

      网友评论

          本文标题:Spring Boot多数据源Mybatis配置爬坑记录

          本文链接:https://www.haomeiwen.com/subject/rtsfextx.html