Springboot 配置多数据源Mybatis的UnderScore不生效

摘要

本文是一篇问题解决经验分享的文章。因为在网上没有搜到相关的介绍文章,而在遇到这个问题的解决过程中,犯过一些想当然的错误,所以记录在此,希望能够对后面遇到此问题的朋友有所帮助

问题

参考官方文档进行了相关配置。

https://github.com/mybatis/spring-boot-starter/blob/master/mybatis-spring-boot-autoconfigure/src/main/java/org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.java

  1. 通过MybatisProperties 将application.yml文件中mybatis相关配置映射到properties文件中
  2. 通过MybatisAutoConfiguration注入SqlSessionFactory的Bean到容器中

通过这个配置,就可以在代码中开心的通过mybatis的操作数据库了。

但是这种方式只能配置一种数据源,像下面这样再配置一个

  @Bean(name = "siteASqlSessionFactory")
  @ConditionalOnMissingBean
  public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setDataSource(dataSource);
    factory.setVfs(SpringBootVFS.class);
    if (StringUtils.hasText(this.properties.getConfigLocation())) {
      factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
    }
    applyConfiguration(factory);
    if (this.properties.getConfigurationProperties() != null) {
      factory.setConfigurationProperties(this.properties.getConfigurationProperties());
    }
    if (!ObjectUtils.isEmpty(this.interceptors)) {
      factory.setPlugins(this.interceptors);
    }
    if (this.databaseIdProvider != null) {
      factory.setDatabaseIdProvider(this.databaseIdProvider);
    }
    if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
      factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
    }
    if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
      factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
    }
    if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
      factory.setMapperLocations(this.properties.resolveMapperLocations());
    }

    return factory.getObject();
  }

问题1:如果再配置一个,像上面那样,会发现报错,找不到对应的表schema,sql执行失败。

SprintBootVFS
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table ‘site.post’ doesn’t exist
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1052)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4098)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4030)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2671)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2621)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1557)
at com.alibaba.druid.pool.DruidPooledStatement.executeQuery(DruidPooledStatement.java:140)
at com.taobao.tddl.atom.jdbc.TStatementWrapper.executeQuery(TStatementWrapper.java:260)
at com.taobao.tddl.group.jdbc.TGroupStatement.executeQueryOnConnection(TGroupStatement.java:426)
at com.taobao.tddl.group.jdbc.TGroupStatement3.tryOnDataSource(TGroupStatement.java:439)atcom.taobao.tddl.group.jdbc.TGroupStatement3.tryOnDataSource(TGroupStatement.java:430)
at

然后就改成下面这样,另外一个数据源改成这样的配置

@Bean(name = "siteASqlSessionFactory")
    public SqlSessionFactory siteASqlSessionFactory(@Qualifier("siteADataSource") DataSource siteATaskDataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(siteATaskDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(SiteADataSourceConfig.MAPPER_LOCATION));
        return sessionFactory.getObject();
    }

问题2:问题就遇到了,如题所说,mapUnderScoreToCamelCase配置不生效,
一开始没理解为什么不生效,明明application.yml中已经配置了。但是分析了一下就知道,因为mapUnderScoreToCamelCase是Configuration的一个属性,之前习惯了这种配置,框架帮忙做了,不了解其原理,在这边SqlSessionFactory中根本没有配置configuration对象,当然不生效。

所以现在了解了问题,mapUnderScoreToCamelCase是Configuration的一个属性,Configuration需要注入到SqlSesssionFactory中。然后配置多个数据源后,为什么会找不到第二个数据源的schema了。通过debug发现,

Configuration类中有一个变量Environment,

protected Environment environment;

Environment中有个DataSource对象,这个之前我们介绍过,是数据库连接对象,所以问题比较清楚了,当注入第一个sqlSessionFactory后数据库连接时正常的,但是当注入第二个数据源的sqlSessionFactory,由于Configuration.Environment.DataSource已经配置了第一个数据源的信息,所以在web容器启动后,进行数据库操作时,会报找不到数据库schema

public final class Environment {
  private final String id;
  private final TransactionFactory transactionFactory;
  private final DataSource dataSource;
  }

解决

找到root cause后,解决就简单了。配置两个Configuration就好了
数据源1

  @Bean(name = "siteASqlSessionFactory")
    public SqlSessionFactory siteASqlSessionFactory(@Qualifier("siteADataSource") DataSource siteADataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(siteADataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(siteADataSourceConfig.MAPPER_LOCATION));
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session
                .Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        sessionFactory.setConfiguration(configuration);
        return sessionFactory.getObject();
    }

数据源2

```
  @Bean(name = "siteBSqlSessionFactory")
    public SqlSessionFactory siteASqlSessionFactory(@Qualifier("siteBDataSource") DataSource siteADataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(siteBDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(siteBDataSourceConfig.MAPPER_LOCATION));
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session
                .Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        sessionFactory.setConfiguration(configuration);
        return sessionFactory.getObject();
    }

扫面二维码,了解更多

这里写图片描述

©️2020 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值