Spring Boot JPA中的动态数据源

我有一个应用程序,它需要连接到几个不同的架构,但都需要连接到同一类型(ORACLE)。决定哪个模式来自UI。

如果用户选择了schema1,则实体应保留在Schema1中;如果选择其他,则实体应位于所选的其他模式中。

我正在使用带有依赖项“ spring-boot-starter-data-jpa”的Spring Boot" title="Spring Boot">Spring Boot + Hibernate

我已经创建了如下所示的数据源类,以便可以在调用数据层之前每次更改数据源对象中的“ schemaName”。

@Component

public class SchemaDatasource extends AbstractDataSource {

private String schemaName;

@Autowired

private DSManager dsm;

public void setSchemaName(String schemaName) {

this.schemaName = schemaName;

}

@Override

public Connection getConnection() throws SQLException {

if (schemaName!= null)

return dsm.getConnection(schemaName);

else

return null;

}

@Override

public Connection getConnection(String username, String password) throws SQLException {

if (schemaName!= null)

return dsm.getConnection(schemaName);

else

return null;

}

}

我的问题是在启动过程中,“

HibernateJpaAutoConfiguration”尝试创建sessionfactory。在创建过程中,它尝试检查与数据源的连接,但是由于schemaName在启动时为null,因此我的SchemaDatasource返回的null连接导致应用程序引导失败。

有没有办法解决这个问题。我期望与SessionFactory类似,在hibernate状态下没有选项。

同样在RoutingDatasource的情况下,我必须设置defaultDatasource。

Spring boot version: 1.5.9.RELEASE

回答:

这是我对DataSource的实现

public class DataSourceManager implements DataSource {

private Map<String, DataSource> dataSources = new HashMap<>();

private DataSource dataSource;

public DataSourceManager() {

}

public DataSourceManager(DataSource dataSource) {

this.dataSource = dataSource;

}

public void add(String name, DataSource dataSource) {

dataSources.put(name, dataSource);

}

public void switchDataSource(String name) {

dataSource = dataSources.get(name);

}

@Override

public PrintWriter getLogWriter() throws SQLException {

return dataSource.getLogWriter();

}

@Override

public void setLogWriter(PrintWriter out) throws SQLException {

dataSource.setLogWriter(out);

}

@Override

public void setLoginTimeout(int seconds) throws SQLException {

dataSource.setLoginTimeout(seconds);

}

@Override

public int getLoginTimeout() throws SQLException {

return dataSource.getLoginTimeout();

}

@Override

public Logger getParentLogger() throws SQLFeatureNotSupportedException {

return dataSource.getParentLogger();

}

@Override

public <T> T unwrap(Class<T> iface) throws SQLException {

return dataSource.unwrap(iface);

}

@Override

public boolean isWrapperFor(Class<?> iface) throws SQLException {

return dataSource.isWrapperFor(iface);

}

@Override

public Connection getConnection() throws SQLException {

return dataSource.getConnection();

}

@Override

public Connection getConnection(String username, String password) throws SQLException {

return dataSource.getConnection(username, password);

}

}

这是我的配置

@Configuration

public class DataSourceConfig {

@Autowired

private Environment env;

public DataSource makeDataSource(String name) {

return DataSourceBuilder.create()

.driverClassName(env.getProperty("spring.datasource." + name + ".driver-class-name"))

.url(env.getProperty("spring.datasource." + name + ".url")).build();

}

@Bean

public DataSource dataSource() {

DataSourceManager dataSourceManager = new DataSourceManager();

dataSourceManager.add("test1", makeDataSource("test1"));

dataSourceManager.add("test2", makeDataSource("test2"));

dataSourceManager.switchDataSource("test1");

return dataSourceManager;

}

}

这是application.yml

spring:

jpa:

hibernate:

ddl-auto: create

properties:

hibernate:

dialect: org.hibernate.dialect.H2Dialect

datasource:

test1:

name: test2

url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

driver-class-name: org.h2.Driver

username: h2

password: h2

test2:

name: test1

url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

driver-class-name: org.h2.Driver

username: h2

password: h2

以上是 Spring Boot JPA中的动态数据源 的全部内容, 来源链接: utcz.com/qa/429747.html

回到顶部