Hibernate Spring boot JPA中的动态数据源

Hibernate Spring boot JPA中的动态数据源,hibernate,spring-boot,spring-orm,Hibernate,Spring Boot,Spring Orm,我有一个应用程序,需要连接到几个不同的模式,但都是相同类型的(ORACLE)。决定哪个模式来自UI 若用户选择schema1,那个么实体应该在schema1中保持,若选择other,那个么它应该在所选的other模式中 我使用SpringBoot+Hibernate和依赖项“SpringBootStarterDataJPA” 我创建了一个如下所示的datasource类,以便每次调用数据层之前都可以更改datasource对象中的“schemaName” @Component public cl

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

若用户选择schema1,那个么实体应该在schema1中保持,若选择other,那个么它应该在所选的other模式中

我使用SpringBoot+Hibernate和依赖项“SpringBootStarterDataJPA”

我创建了一个如下所示的datasource类,以便每次调用数据层之前都可以更改datasource对象中的“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;
    }

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

有没有办法解决这个问题。我期望类似于hibernate中带有Nooptions的SessionFactory

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

Spring boot version: 1.5.9.RELEASE

下面是我对数据源的实现

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);
    }
}
这是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

谢谢,但是我在转换方面没有问题。问题是在不配置初始数据源的情况下引导应用程序。好的,我给出了一个更好的答案,看一看,我知道这个问题比较老,但您能给出一个如何在代码中切换数据源的使用示例吗?我也很好奇这将如何与事务经理(JpaRepository)和实体经理一起工作
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