Springboot 配置多資料來源Mybatis的UnderScore不生效
摘要
本文是一篇問題解決經驗分享的文章。因為在網上沒有搜到相關的介紹文章,而在遇到這個問題的解決過程中,犯過一些想當然的錯誤,所以記錄在此,希望能夠對後面遇到此問題的朋友有所幫助
問題
參考官方文件進行了相關配置。
- 通過MybatisProperties 將application.yml檔案中mybatis相關配置對映到properties檔案中
- 通過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) at com.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();
}
掃面二維碼,瞭解更多
相關文章
- SpringBoot 配置多資料來源 MyBatisSpring BootMyBatis
- springboot+druid+mybatis plus的多資料來源配置Spring BootUIMyBatis
- Springboot 多資料來源配置,結合tk-mybatisSpring BootMyBatis
- MyBatis配置多資料來源MyBatis
- SpringBoot 的多資料來源配置Spring Boot
- springBoot 多資料來源配置Spring Boot
- springboot多資料來源配置Spring Boot
- SpringBoot配置多資料來源Spring Boot
- SpringBoot 整合多資料來源(MyBatis + Druid)Spring BootMyBatisUI
- Springboot通過AOP整合多資料來源,分析@Transaction切換資料來源不生效問題Spring Boot
- 基於SpirngBoot2.0+ 的 SpringBoot+Mybatis 多資料來源配置Spring BootMyBatis
- 全程解析,MyBatis在SpringBoot中的動態多資料來源配置MyBatisSpring Boot
- spring多資料來源下 事務不生效Spring
- SpringBoot多資料來源Spring Boot
- springboot新增多資料來源連線池並配置MybatisSpring BootMyBatis
- SpringBoot整合MyBatis-Plus實現多資料來源操作Spring BootMyBatis
- 【教程】Spring+Mybatis環境配置多資料來源SpringMyBatis
- Springboot整合mybatis實現多資料來源所遇到的問題Spring BootMyBatis
- SpringBoot | 3.1 配置資料來源Spring Boot
- springboot 配置多個資料來源,@MapperScan方式繫結Spring BootAPP
- 多資料來源配置
- springboot 配置DRUID資料來源的方法Spring BootUI
- SpringBoot資料來源相關配置Spring Boot
- 基於註解的springboot+mybatis的多資料來源元件的實現Spring BootMyBatis元件
- SpirngBoot整合Mybatis Plus多資料來源bootMyBatis
- Spring多資料來源配置Spring
- web 配置多資料來源Web
- 談一談Spring-Mybatis在多資料來源配置上的坑SpringMyBatis
- 談一談 Spring-Mybatis 在多資料來源配置上的坑SpringMyBatis
- Spring Boot 2.x基礎教程:MyBatis的多資料來源配置Spring BootMyBatis
- SpringBoot+Mybatis+ Druid+PageHelper 實現多資料來源並分頁Spring BootMyBatisUI
- springboot 2 Hikari 多資料來源配置問題(dataSourceClassName or jdbcUrl is required)Spring BootJDBCUI
- springboot(七):springboot+mybatis多資料Spring BootMyBatis
- Spring Boot + Mybatis 多資料來源配置實現讀寫分離Spring BootMyBatis
- 資料來源(DataSource)是什麼以及SpringBoot中資料來源配置Spring Boot
- mybatis 多資料來源動態切換MyBatis
- Spring Boot 多資料來源配置Spring Boot
- Spring Boot 配置多資料來源Spring Boot