I have a endpoint which exports the data from the database and I have another endpoint which imports the data . I want to export the data from the one database and import to other but that should be done at runtime , somewhat like this : To export
http://localhost:8080/export?source=oracle
To import
http://localhost:8080/import?source=mariadb
This is how I am reading the property file currently:
@Component
public class ExportDBConfiguration extends DBConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(ExportDBConfiguration.class);
@Value("${export.database.url}")
private String dbUrl;
@Value("${export.database.user}")
private String dbUser;
@Value("${export.database.password}")
private String dbPassword;
public Properties getDatabaseProperties() {
LOG.info("Setting export database specific properties.");
return getDatabaseProperties(dbUser, dbPassword);
}
public String getDBUrl() {
String absoluteUrl = getDBUrl(dbUrl);
LOG.info("Absolute db url is :: {} ", absoluteUrl);
return absoluteUrl;
}
}
To achieve this I thought of creating the separate properties file and then read from them based on the parameter source of the endpoint , but this approach is not working . Any idea how can it be done or a better approach to achieve this loose coupling ??
CodePudding user response:
You should use multiple DataSources
in your Spring Boot App.
There are several Articles, Tutorials and SO answers that explain this topic.
For starters, you add the config of your datasources
in the application.properties
file:
# First Database
spring.datasource.url = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]
spring.datasource.driverClassName = oracle.jdbc.OracleDriver
# Second DB
spring.secondDatasource.url = [url]
spring.secondDatasource.username = [username]
spring.secondDatasource.password = [password]
spring.secondDatasource.driverClassName = [your Other Driver]
# To let Hibernate autodetect the Dialect
spring.jpa.database=default
Then create config classes for all your DataSources
:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
basePackages = { "insert.your.repo.package.here" }
)
public class FirstDbConfig{
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "spring.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("insert.your.entity.package.here")
.persistenceUnit("firstDB")
.build();
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("entityManagerFactory") EntityManagerFactory
entityManagerFactory
) {
return new JpaTransactionManager(entityManagerFactory);
}
}
Then another Config class for your second DB:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "secondEntityManagerFactory",
transactionManagerRef = "secondTransactionManager",
basePackages = { "path.to.your.second.repo" }
)
public class SecondDbConfig {
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "spring.secondDatasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean
barEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("secondDataSource") DataSource dataSource
) {
return
builder
.dataSource(dataSource)
.packages("path.to.your.second.entities.package")
.persistenceUnit("secondDB")
.build();
}
@Bean(name = "secondTransactionManager")
public PlatformTransactionManager barTransactionManager(
@Qualifier("secondEntityManagerFactory") EntityManagerFactory
secondEntityManagerFactory
) {
return new JpaTransactionManager(secondEntityManagerFactory);
}
}
A lot of the part above is explained in this, this, and this article.
And then depending on what database name is in your query params, you use the specific Repos and Models.
You can of course add more than 2 DataSources
.
CodePudding user response:
You will need to define the Datasources and their properties first. Then depending on which version of Springboot you are using, you must define the beans for the DataSources.
@Qualifier("mariadb")
@Autowired
private DataSource mariaDbDataSource;
@Qualifier("oracle")
@Autowired
private DataSource oracleDataSource;
if(source="oracle"){
oracleDataSource.doSomething();
}