前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springboot 配置多数据源Mybatis的MapUnderScoreToCamelCase不生效

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

作者头像
方丈的寺院
发布2019-08-05 17:27:34
5.4K2
发布2019-08-05 17:27:34
举报
文章被收录于专栏:方丈的寺院方丈的寺院

摘要

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

问题

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

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的操作数据库了。

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

代码语言:javascript
复制
@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.TGroupStatement$3.tryOnDataSource(TGroupStatement.java:439) at com.taobao.tddl.group.jdbc.TGroupStatement$3.tryOnDataSource(TGroupStatement.java:430) at

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

代码语言:javascript
复制
@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,

代码语言:javascript
复制
protected Environment environment;

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

代码语言:javascript
复制
public final class Environment {
  private final String id;
  private final TransactionFactory transactionFactory;
  private final DataSource dataSource;
  }

解决

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

代码语言:javascript
复制
@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

代码语言:javascript
复制
```
  @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();
    }
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 方丈的寺院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 摘要
  • 问题
  • 解决
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档