美文网首页
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