美文网首页
SpringBoot 连接多个数据库

SpringBoot 连接多个数据库

作者: 清十郎sama | 来源:发表于2019-12-23 15:12 被阅读0次

这里我们假设大家已经熟悉 SpringBoot + JPA 连接单个数据库的开发。如果不熟悉,可以参考:Spring Boot 使用数据库

  1. Pom 依赖和但数据库没有区别,照常引入。
  2. JAP 的 Entity Object 和 Repository 写法没有任何区别,照常编写。
  3. 写数据库配置时,过去我们只需定义一个 spring.datasource.* 即可。而现在需要连接多个数据库,我们的配置方式略有变化,配置文件 application.yml 如下:
app:
  datasource:
    first:
      jdbc-url: jdbc:db2://xxx.xxx.xxx.xxx:50000/xxx
      username: xxx
      password: xxx
      maximum-pool-size: 30
      continueOnError: true
    second:
      jdbc-url: jdbc:db2://xxx.xxx.xxx.xxx:50000/xxx
      username: xxx
      password: xxx
      maximum-pool-size: 30
      continueOnError: true

这里的 first 和 second 是自定义名,稍后在写数据库的配置类时会用到。

  1. 写数据库配置类
  • 第一个数据库配置(FirstDataSourceConfig.java)
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.taikang.cms.warningservice.domain.first"},
        entityManagerFactoryRef = "FirstEntityManagerFactory",
        transactionManagerRef = "FirstTransactionManager")
public class FirstDataSourceConfig {
 
    @Primary
    @Bean(name="FirstDataSource")
    @ConfigurationProperties("app.datasource.first")
    public HikariDataSource dataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }
 
    @Primary
    @Bean(name ="FirstEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
                                                                          @Qualifier("FirstDataSource") DataSource dataSource){
        return builder
                .dataSource(dataSource)
                .packages("com.taikang.cms.warningservice.domain.first")
                .persistenceUnit("first")
                .build();
    }
 
    @Primary
    @Bean(name ="FirstTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("FirstEntityManagerFactory") EntityManagerFactory customerEntityManagerFactory
    ) {
        return new JpaTransactionManager(customerEntityManagerFactory);
    }
}
  • 第二个数据库配置(SecondDataSourceConfig.java)
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.taikang.cms.warningservice.domain.second"},
        entityManagerFactoryRef = "SecondEntityManagerFactory",
        transactionManagerRef = "SecondTransactionManager")
public class SecondDataSourceConfig {
 
    @Bean(name="SecondDataSource")
    @ConfigurationProperties("app.datasource.second")
    public HikariDataSource dataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }
 
    @Bean(name ="SecondEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
                                                                          @Qualifier("SecondDataSource") DataSource dataSource){
        return builder
                .dataSource(dataSource)
                .packages("com.taikang.cms.warningservice.domain.second")
                .persistenceUnit("second")
                .build();
    }
 
    @Bean(name ="SecondTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("FirstEntityManagerFactory") EntityManagerFactory customerEntityManagerFactory
    ) {
        return new JpaTransactionManager(customerEntityManagerFactory);
    }
}
  • 特别注意一下 @EnableJpaRepositories(...) 这个注解,他用来定义 JPA Repositories 所对应的具体数据库源。
  1. 可以了! 启动服务试试看了!

过程碰到的坑

变量名和数据库字段的映射规则(JPA naming strategy)失效了?
通常我们的 sql 命名多个单词都是下划线隔开,而 java 的变量名则是采用驼峰。熟悉 JPA 的伙伴知道,spring 在这里会帮我们自动把下划线命名和驼峰命名进行映射。但不知为何,当我采用多个数据源后,这个自动映射就失效了,会报错,诸如找不到字段,找不到对应库表等问题。
解决方法,我们只需要稍微修改一下我们数据源配置类的 entityManagerFactory 方法,改写代码如下:

@Bean(name ="XXX")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
                                                                      @Qualifier("XXX") DataSource dataSource){
    return builder
            .dataSource(dataSource)
            .packages("com.demo.xxx.xxx")
            .persistenceUnit("xxx")
            .properties(jpaProperties())
            .build();
}
 
protected Map<String, Object> jpaProperties() {
    Map<String, Object> props = new HashMap<>();
    props.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
    props.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
    return props;
}

参考:stackoverflow.com/questions/40509395/cant-set-jpa-naming-strategy-after-configuring-multiple-data-sources-spring-1

相关文章

网友评论

      本文标题:SpringBoot 连接多个数据库

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