[英]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.