Java 使用SpringBoot的动态数据源
我正在使用SpringBoot编写一个微服务,需要动态选择数据源。我将根据参数选择数据源。每个数据源都指向具有相同模式(相同的表、触发器、存储过程等)的Oracle数据库。我如何实现这个要求?我实现了类似的东西 我使用application.properties来存储数据源连接Java 使用SpringBoot的动态数据源,java,spring-boot,dynamic,datasource,Java,Spring Boot,Dynamic,Datasource,我正在使用SpringBoot编写一个微服务,需要动态选择数据源。我将根据参数选择数据源。每个数据源都指向具有相同模式(相同的表、触发器、存储过程等)的Oracle数据库。我如何实现这个要求?我实现了类似的东西 我使用application.properties来存储数据源连接 Datasource drive name spring.datasource.driver-class-name= spring.datasource.url= spring.datasource.username=
Datasource drive name
spring.datasource.driver-class-name=
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
有一些关于如何读取和写入属性的代码示例
创建端点以更新属性
@PutMapping("/update")
public ResponseEntity<?> updateConnection(@RequestBody final List<ConfigurationProperty> properies) {
LOGGER.trace("Updating data source properties ");
for (final ConfigurationProperty configurationProperty : properies) {
config.getConfigurationProvider().persistDatabaseProperty(configurationProperty.getPropertyName(),
configurationProperty.getPropertyValue());
}
}
}
return new ResponseEntity<> (HttpStatus.OK);
}
@PutMapping(“/update”)
公共响应属性更新连接(@RequestBody final List properties){
LOGGER.trace(“更新数据源属性”);
用于(最终配置属性配置属性:属性){
config.getConfigurationProvider().persistDatabaseProperty(configurationProperty.getPropertyName(),
configurationProperty.getPropertyValue());
}
}
}
返回新的响应状态(HttpStatus.OK);
}
经验中的另一个技巧是,在执行更新端点之前ping连接。:)
对于我的实现,唯一的结论是,用户需要重新启动服务器才能对服务器进行更改 在启动时配置所有数据源,然后: 要么: a。使用实现每个数据源的不同repo类,在调用相应的repo之前检查参数
b。有一个repo类检查参数并使用相应的数据源进行查询。必须在application.properties中实现两个配置数据源,然后配置两个EntityManagerFactory和TransactionManager。您可以使用不同的存储库在两个数据源之间切换 应用程序属性
first.datasource.url=jdbc:oracle:thin:@//host:1521/firstdb
first.datasource.username=first
first.datasource.password=first
first.datasource.driver-class-name=oracle.jdbc.OracleDriver
second.datasource.url=jdbc:oracle:thin:@//host:1521/firstdb
second.datasource.username=second
second.datasource.password=second
second.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.jpa.database=default
向每个实体和存储库发送两个包,向设置发送两个配置
第一名:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
basePackages = { "com.system.first.repo" }
)
public class FirstDbConfig {
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "first.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean
entityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("dataSource") DataSource dataSource
) {
return builder
.dataSource(dataSource)
.packages("com.system.first.domain")
.persistenceUnit("first")
.build();
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("entityManagerFactory") EntityManagerFactory
entityManagerFactory
) {
return new JpaTransactionManager(entityManagerFactory);
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "secondEntityManagerFactory",
transactionManagerRef = "secondTransactionManager",
basePackages = { "com.system.second.repo" }
)
public class SecondDbConfig {
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "second.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean
secondEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("secondDataSource") DataSource dataSource
) {
return
builder
.dataSource(dataSource)
.packages("com.system.second.domain")
.persistenceUnit("second")
.build();
}
@Bean(name = "secondTransactionManager")
public PlatformTransactionManager secondTransactionManager(
@Qualifier("secondEntityManagerFactory") EntityManagerFactory
secondEntityManagerFactory
) {
return new JpaTransactionManager(secondEntityManagerFactory);
}
}
秒:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
basePackages = { "com.system.first.repo" }
)
public class FirstDbConfig {
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "first.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean
entityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("dataSource") DataSource dataSource
) {
return builder
.dataSource(dataSource)
.packages("com.system.first.domain")
.persistenceUnit("first")
.build();
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("entityManagerFactory") EntityManagerFactory
entityManagerFactory
) {
return new JpaTransactionManager(entityManagerFactory);
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "secondEntityManagerFactory",
transactionManagerRef = "secondTransactionManager",
basePackages = { "com.system.second.repo" }
)
public class SecondDbConfig {
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "second.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean
secondEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("secondDataSource") DataSource dataSource
) {
return
builder
.dataSource(dataSource)
.packages("com.system.second.domain")
.persistenceUnit("second")
.build();
}
@Bean(name = "secondTransactionManager")
public PlatformTransactionManager secondTransactionManager(
@Qualifier("secondEntityManagerFactory") EntityManagerFactory
secondEntityManagerFactory
) {
return new JpaTransactionManager(secondEntityManagerFactory);
}
}
在springboot中尝试此AbstractRoutingDataSource