java - Spring boot: how to correctly configure and use multiple datasources
问题描述
I am trying to setup multiple datasources correctly in Spring Boot with JPA 2.1.4.RELEASE
.
Setup is something like below:
- DEV: 1 server with 2 dbs:
DB1
andDB2
.DB1
hasABC
table andDB2
hasXYZ
table. - PROD: 2 servers PROD1 and PROD2 both live-live. Each PROD server has same setup as DEV i.e. PROD1 has
DB1
andDB2
; and PROD2 also hasDB1
andDB2
.
So far I have successfully completed DEV setup. I have 2 configurations:
- for
DB1
- for
DB2
Then I have 2 Repos:
- for
ABC
which writes inDB1
- for
XYZ
which writes inDB2
Now in PROD, I need to write data in both servers(PROD1 and 2) in single transaction using spring boot.
I can see one example here which try to provide some sort of solution, but problem is it will ask to create duplicate Dao and Service class, which I think is not a good way of solving this problem and need to understand how to properly configure those properties in application.properties and DataSourceConfig.java
application-dev.properties
datasource.db1.url=jdbc:sqlserver://localhost:1234;databaseName=db1;
datasource.db1.username=user
datasource.db1.password=pwd
datasource.db1.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
datasource.db2.url=jdbc:sqlserver://localhost:1234;databaseName=db2;
datasource.db2.username=user
datasource.db2.password=pwd
datasource.db2.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
application-prod.properties
datasource.prod1.db1.url=jdbc:sqlserver://prodserver1:1234;databaseName=db1;
datasource.prod1.db1.username=user
datasource.prod1.db1.password=pwd
datasource.prod1.db1.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
datasource.prod1.db2.url=jdbc:sqlserver://prodserver1:1234;databaseName=db2;
datasource.prod1.db2.username=user
datasource.prod1.db2.password=pwd
datasource.prod1.db2.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
datasource.prod2.db1.url=jdbc:sqlserver://prodserver2:1234;databaseName=db1;
datasource.prod2.db1.username=user
datasource.prod2.db1.password=pwd
datasource.prod2.db1.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
datasource.prod2.db2.url=jdbc:sqlserver://prodserver2:1234;databaseName=db2;
datasource.prod2.db2.username=user
datasource.prod2.db2.password=pwd
datasource.prod2.db2.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
Db1DataSourceConfig.java
@Configuration
@EnableJpaRepositories(
basePackages = "demo.repos.db1",
entityManagerFactoryRef = "db1EntityManagerFactory",
transactionManagerRef = "db1TransactionManager")
public class Db1DataSourceConfig {
@Autowired
private Environment env;
@Bean
@ConfigurationProperties(prefix="datasource.db1")
public DataSourceProperties db1DataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DataSource db1DataSource() {
DataSourceProperties dataSourceProperties = db1DataSourceProperties();
return DataSourceBuilder.create()
.driverClassName(dataSourceProperties.getDriverClassName())
.url(dataSourceProperties.getUrl())
.username(dataSourceProperties.getUsername())
.password(dataSourceProperties.getPassword())
.build();
}
@Bean
public PlatformTransactionManager db1TransactionManager() {
EntityManagerFactory factory = db1EntityManagerFactory().getObject();
return new JpaTransactionManager(factory);
}
@Bean
public LocalContainerEntityManagerFactoryBean db1EntityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(db1DataSource());
factory.setPackagesToScan(new String[]{"demo.entities.db1"});
factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql"));
factory.setJpaProperties(jpaProperties);
return factory;
}
}
Db2DataSourceConfig.java
@Configuration
@EnableJpaRepositories(
basePackages = "demo.repos.db2",
entityManagerFactoryRef = "db2EntityManagerFactory",
transactionManagerRef = "db2TransactionManager")
public class Db2DataSourceConfig {
@Autowired
private Environment env;
@Bean
@ConfigurationProperties(prefix="datasource.db2")
public DataSourceProperties db2DataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DataSource db2DataSource() {
DataSourceProperties dataSourceProperties = db2DataSourceProperties();
return DataSourceBuilder.create()
.driverClassName(dataSourceProperties.getDriverClassName())
.url(dataSourceProperties.getUrl())
.username(dataSourceProperties.getUsername())
.password(dataSourceProperties.getPassword())
.build();
}
@Bean
public PlatformTransactionManager db2TransactionManager() {
EntityManagerFactory factory = db2EntityManagerFactory().getObject();
return new JpaTransactionManager(factory);
}
@Bean
public LocalContainerEntityManagerFactoryBean db2EntityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(db2DataSource());
factory.setPackagesToScan(new String[]{"demo.entities.db2"});
factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql"));
factory.setJpaProperties(jpaProperties);
return factory;
}
}
解决方案
推荐阅读
- python - Python/Scrapy 如何进入更深的链接并返回
- android-activity - 使用 JavaFXPorts 从服务启动 JavaFX 应用程序
- xamarin - 将大文件上传到 Xamarin 中的 Azure 媒体服务
- python - segfault - c_void_p 到 c_byte 数组
- c - 了解在 C 中使用双指针创建单链表的代码
- javascript - 条带发票项目并不总是在一张发票中一起发送
- javascript - 如何从下拉列表中选择具有 SELECT OPTION 标签的元素?
- php - 向下滚动时,yii2 在下拉 div 中越来越多地显示通知
- security - 使用 OpenSSL 对 .tar.gz 文件进行跨平台代码签名?
- python - 在子字符串之后查找文本直到python中的行尾