我的 Spring Boot 应用程序在应用程序启动时不知道要连接到哪个数据库。它将在运行时接收 HTTP 请求正文中的输入(包括 dbtype、dbservername 等),并且它应该基于此输入连接到数据库实例。
对于我在 StackOverflow 上检查过的类似问题,人们建议了预先创建数据源实例,然后在运行时根据输入进行切换的方法。但是,我不想对不同数据库的配置进行硬编码。我希望应用程序在运行时创建 JdbcTemplate、Datasource 和 TransactionManager 实例。
这是我迄今为止在运行时创建 JdbcTemplate 和 Datasource 实例的尝试:
class DBConfig{
private DataSource getMSSQLDatasource(String servername){
// create MSSQL datasource using the servername
}
private DataSource getDB2Datasource(String servername){
// create DB2 datasource using the servername
}
private JdbcTemplate setJdbcTemplate(String dbtype, String servername){
return new JdbcTemplate(dbtype.equals("DB2") ? getDB2Datasource(servername) : getMSSQLDatasource(servername));
}
}
所以我可以在运行时创建JdbcTemplate和Datasource。 但我还想使用 @Transactional 将一些查询作为事务执行,为此我需要一个 TransactionManager。 我不知道如何在运行时动态配置它。
所以我有两个问题:
我尝试了一种解决方法,到目前为止似乎效果很好。 任何建议都会非常有帮助。
创建了一个实现 PlatformTransactionManager 的自定义类(DynamicTransactionManager):
@Component
class DynamicTransactionManager implements PlatformTransactionManager{
private DataSource datasource;
private DataSourceTransactionManager transactionManager;
public void setDatasource(DataSource datasource){
this.datasource = datasource;
this.transactionManager = new DataSourceTransactionManager(datasource);
}
@Override
public TransactionStatus getTransaction (TransactionDefinition definition) throws TransactionException {
return transactionManager.getTransaction (definition);
}
@Override
public void commit (TransactionStatus status) throws TransactionException {
transactionManager.commit(status);
}
@Override
public void rollback(TransactionStatus status) throws TransactionException {
transactionManager.rollback(status);
}
}
现在在 DBConfig 类中,创建 JdbcTemplate 时,访问 DynamicTransactionManager 的 bean 并动态设置 DataSource,如下所示:
class DBConfig{
private DataSource getMSSQLDatasource(String servername){
// create MSSQL datasource using the servername
}
private DataSource getDB2Datasource(String servername){
// create DB2 datasource using the servername
}
private JdbcTemplate setJdbcTemplate(String dbtype, String servername){
DataSource datasource = dbtype.equals("DB2") ? getDB2Datasource(servername) : getMSSQLDatasource(servername);
// CONFIGURE TRANSACTION MANAGER
DynamicTransactionManager transactionManager = applicationContext.getBean(DynamicTransactionManager.class);
transactionManager.setDataSource(datasource);
return new JdbcTemplate(datasource);
}
}