簡體   English   中英

Spring Boot如何連接多個數據庫

[英]How to connect multiple databases in Spring Boot

我想開發一個應用程序來連接到多個 oracle 數據庫並從每個數據庫的同一個表中獲取數據。

我已經嘗試為每個數據庫使用多個數據源並從表中獲取數據。

資源: https ://medium.com/@joeclever/using-multiple-datasources-with-spring-boot-and-spring-data-6430b00c02e7

DB1 配置:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "CU1EntityManagerFactory", basePackages = {
      "com.javatechie.multiple.ds.api.cu1.repository" })
public class CU1Config {
   @Primary
   @Bean(name = "CU1DataSource")
   @ConfigurationProperties(prefix = "spring.cu1.datasource")
   public DataSource dataSource() {
      return DataSourceBuilder.create().build();
   }

   @Primary
   @Bean(name = "CU1EntityManagerFactory")
   public LocalContainerEntityManagerFactoryBean CU1EntityManagerFactory(EntityManagerFactoryBuilder builder,
                                                        @Qualifier("CU1DataSource") DataSource dataSource) {
      HashMap<String, Object> properties = new HashMap<>();
      properties.put("hibernate.hbm2ddl.auto", "update");
      properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle12cDialect");
      return builder.dataSource(dataSource).properties(properties)
            .packages("com.javatechie.multiple.ds.api.model").persistenceUnit("Unit").build();
   }

}

DB2 配置:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "CU2EntityManagerFactory", basePackages = {
      "com.javatechie.multiple.ds.api.cu2.repository" })
public class CU2Config {

   @Bean(name = "CU2DataSource")
   @ConfigurationProperties(prefix = "spring.cu2.datasource")
   public DataSource dataSource() {
      return DataSourceBuilder.create().build();
   }

   @Bean(name = "CU2EntityManagerFactory")
   public LocalContainerEntityManagerFactoryBean CU2EntityManagerFactory(EntityManagerFactoryBuilder builder,
                                                        @Qualifier("CU2DataSource") DataSource dataSource) {
      HashMap<String, Object> properties = new HashMap<>();
      properties.put("hibernate.hbm2ddl.auto", "update");
      properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle12cDialect");
      return builder.dataSource(dataSource).properties(properties)
            .packages("com.javatechie.multiple.ds.api.model").persistenceUnit("Unit").build();
   }

}

但是我面臨的問題是對於每個數據源,我必須創建一個單獨的配置類以及一個專用的存儲庫和服務,這是代碼可重復性,盡管每個數據庫的工作都是相同的,以從特定表中獲取數據。

而且將來如果我想添加任何新數據庫,我必須再次重復上述相同的過程。

非常感謝有關更好的代碼可重用性方法的任何幫助。

您可以直接通過屬性文件進行操作

spring.datasource.jdbcUrl = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]
spring.second-datasource.jdbcUrl = [url]
spring.second-datasource.username = [username]
spring.second-datasource.password = [password]

然后您需要為數據源創建配置:

@Configuration
@PropertySource({"classpath:persistence-multiple-db-boot.properties"})
@EnableJpaRepositories(
  basePackages = "com.baeldung.multipledb.dao.user",
  entityManagerFactoryRef = "userEntityManager",
  transactionManagerRef = "userTransactionManager")
public class PersistenceUserAutoConfiguration {
    
    @Primary
    @Bean
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource userDataSource() {
        return DataSourceBuilder.create().build();
    }
    // userEntityManager bean 

    // userTransactionManager bean
}

第二個的配置:

@Configuration
@PropertySource({"classpath:persistence-multiple-db-boot.properties"})
@EnableJpaRepositories(
  basePackages = "com.baeldung.multipledb.dao.product", 
  entityManagerFactoryRef = "productEntityManager", 
  transactionManagerRef = "productTransactionManager")
public class PersistenceProductAutoConfiguration {
   
    @Bean
    @ConfigurationProperties(prefix="spring.second-datasource")
    public DataSource productDataSource() {
        return DataSourceBuilder.create().build();
    }
   
    // productEntityManager bean 

    // productTransactionManager bean
}

您可以在此處找到有關此實現的更多信息

如果你要創建一個嚴肅的服務,你應該只知道如何配置它們,如何使用它們,以及如何通過 Spring 控制所有數據庫的事務。

您可以在https://github.com/surasint/surasint-examples/tree/master/spring-boot-jdbi/10_spring-boot-two-databases中查看可運行示例和一些解釋(請參閱 README 中可以嘗試的內容。文本)

我在這里復制了一些代碼。

首先,您必須像這樣設置 application.properties

#Database
database1.datasource.url=jdbc:mysql://localhost/testdb
database1.datasource.username=root
database1.datasource.password=root
database1.datasource.driver-class-name=com.mysql.jdbc.Driver

database2.datasource.url=jdbc:mysql://localhost/testdb2
database2.datasource.username=root
database2.datasource.password=root
database2.datasource.driver-class-name=com.mysql.jdbc.Driver

然后將它們定義為提供者(@Bean),如下所示:

@Bean(name = "datasource1")
@ConfigurationProperties("database1.datasource")
@Primary
public DataSource dataSource(){
    return DataSourceBuilder.create().build();
}

@Bean(name = "datasource2")
@ConfigurationProperties("database2.datasource")
public DataSource dataSource2(){
    return DataSourceBuilder.create().build();
}

請注意,我有@Bean(name="datasource1")@Bean(name="datasource2") ,那么當我們需要數據源作為@Qualifier("datasource1")@Qualifier("datasource2")時,您可以使用它,例如

@Qualifier("datasource1")
@Autowired
private DataSource dataSource;

如果您確實關心事務,則必須為它們定義 DataSourceTransactionManager ,如下所示:

@Bean(name="tm1")
@Autowired
@Primary
DataSourceTransactionManager tm1(@Qualifier ("datasource1") DataSource datasource) {
    DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
    return txm;
}

@Bean(name="tm2")
@Autowired
DataSourceTransactionManager tm2(@Qualifier ("datasource2") DataSource datasource) {
    DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
    return txm;
}

然后你可以像這樣使用它

@Transactional //this will use the first datasource because it is @primary

或者

@Transactional("tm2")

最重要的部分,你幾乎找不到任何地方的例子:如果你想要一個方法來提交/回滾兩個數據庫的事務,你需要 tm1 和 tm2 的 ChainedTransactionManager,像這樣:

@Bean(name = "chainedTransactionManager")
public ChainedTransactionManager getChainedTransactionManager(@Qualifier ("tm1") DataSourceTransactionManager tm1, @Qualifier ("tm2") DataSourceTransactionManager tm2){
    return new ChainedTransactionManager(tm1, tm2);
}

要使用它,請在 @Transactional(value="chainedTransactionManager") 方法中添加此注釋,例如

@Transactional(value="chainedTransactionManager")
public void insertAll() {
    UserBean test = new UserBean();
    test.setUsername("username" + new Date().getTime());
    userDao.insert(test);

    userDao2.insert(test);
}

這應該足夠了。 請參閱上面鏈接中的示例和詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM