【问题标题】:How to get Spring Data to handle multiple heterogeneous DataSources?如何让 Spring Data 处理多个异构数据源?
【发布时间】:2015-03-27 19:29:46
【问题描述】:

我已经成功地使用了 Spring 的 Accessing Data With JPA 教程。我自己的 CrudRepository 只需配置一个特定的 DataSource @Bean 就可以自动工作,并且它们之间的内部连接由 Spring Data(或 Spring Boot,很难说是哪个)管理。

但是,我不知道如何让自动管道处理第二个 DataSource @Bean。注入第二个会导致自动配置类在启动期间爆炸。

关于如何做到这一点的任何想法?我为此进行的搜索导致文章讨论了多个同构数据源以实现负载平衡或其他目的,这确实不是我所需要的。我有多个具有完全独立内容的数据库,我需要将它们拉入这个应用程序,我真的很想避免仅仅因为第二个数据库进入混合状态而不得不复制所有自动化配置。

我希望这很简单,但我担心这是自动配置中不受支持的边缘情况。

【问题讨论】:

  • 你在使用Repository注解吗?如果是这样,您是否使用 EnableRepos 设置了配置类或 xml 配置?如果这两个都是真的,我敢打赌你缺少一个 Qualifier 注释。由于它们都扩展了 Repo 接口,因此存在自动装配冲突。添加 Qualifier('datasource1') Qualifier('datasource2') 您的注入可以简单地添加对服务很重要的源的限定符。
  • @AnthonyJClink 我没有使用 Repository 注释,我只是扩展 CrudRepository 接口,如spring.io/guides/gs/accessing-data-jpa所示
  • 您可能需要重新表述您的标题,因为您谈论的是支持来自同一类型 (SQL) 的不同后端的不同类型,而不是 Spring Data 跨存储支持。
  • 如果您在 spring-boot 中添加第二个数据源,您需要将其中一个标记为 @Primary 以便被自动配置识别。
  • @chrylis 我不清楚我的标题如何暗示“跨店支持”。

标签: java spring spring-data spring-boot


【解决方案1】:

您可以创建两个数据源和实体管理器,其中一个 bean 标记为@Primary

@Configuration
@EnableJpaRepositories(basePackages = "io.eddumelendez.springdatajpa.repository1")
public class FirstConfiguration {

    @ConfigurationProperties(prefix = "datasource.postgres")
    @Bean
    @Primary
    public DataSource postgresDataSource() {
        return DataSourceBuilder.create().
                build();
    }

    @Bean(name = "entityManagerFactory")
    @Primary
    public LocalContainerEntityManagerFactoryBean emf1(EntityManagerFactoryBuilder builder){
        return builder
                .dataSource(postgresDataSource())
                .packages("io.eddumelendez.springdatajpa.domain1")
                .persistenceUnit("users")
                .build();
    }

}

另一个数据源的配置:

@Configuration
@EnableJpaRepositories(basePackages = "io.eddumelendez.springdatajpa.repository2", entityManagerFactoryRef = "emf2")
public class SecondConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "datasource.mysql")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean emf2(EntityManagerFactoryBuilder builder){
        return builder
                .dataSource(mysqlDataSource())
                .packages("io.eddumelendez.springdatajpa.domain2")
                .persistenceUnit("customers")
                .build();
    }

}

您的 application.properties 应如下所示:

datasource.mysql.url=jdbc:mysql://localhost:3306/mysql_demo
datasource.mysql.username=root
datasource.mysql.password=root

datasource.postgres.url=jdbc:postgresql://localhost:5432/postgres_demo
datasource.postgres.username=postgres
datasource.postgres.password=postgres

【讨论】:

  • 我将如何使用非主数据源呢?我需要手动构建管道吗?
  • 主要注解将仅由自动配置使用,只是为了不破坏它。如果您使用的是 JdbcTemplate,则必须使用正确的 Qualifier 注释注入 DataSource 才能知道将使用哪个数据源。
  • 我没有使用 JdbcTemplate,我使用的是 CrudRepository,因为它会为我处理所有事情。然而,我看到的唯一方法是通过自动配置,显然不能与多个数据源一起使用。
  • 我已经更新了配置,这样您就可以使用存储库了
  • 该代码适用于哪些版本的 Spring 库?它不能与 Spring 4.1.4、Spring Boot 1.2.1 和 Spring Data JPA 1.7.1 一起编译。
猜你喜欢
  • 2021-11-26
  • 2018-09-20
  • 2020-07-28
  • 2018-08-22
  • 2015-09-07
  • 2018-09-29
  • 1970-01-01
  • 2014-12-06
相关资源
最近更新 更多