使用多个Spring Boot和JDBC数据源

时间:2019-08-02 05:11:32

标签: java spring spring-data datasource spring-jdbc

我在业务中必须解决以下问题。我正在使用Spring进行项目开发,我要连接8个数据源。

将要求告知合同编号,通过此联系电话,我必须选择8个数据源之一并进行客户咨询。

示例: 我有基本的Brazil = 1Spain = 2Germany = 3

  1. 如果合同为id = 1,则应该从Brazil base获取客户数据。
  2. 如果合同为id = 2,则应获取客户数据 来自Spain base
  3. 如果合同为id = 3,则应该从Germany base获取客户数据。

如果使用multitenancyAbstractRouting,我不知道如何解决此问题。而且我不知道如何为此启动代码。

会有人提供任何解决方案和示例吗?

2 个答案:

答案 0 :(得分:1)

Spring可以使用AbstractRoutingDataSource动态确定数据源。但是需要使用ThreadLocal将上下文绑定到当前线程。

如果您生成多个线程或在应用程序中使用异步,这可能会使事情复杂化。

您可以参考简单的范例here

如果您确实需要根据不同的客户端创建数据库连接,则hibernate提供了一种管理Multi-tenancyHibernate Guide的方法。如前所述,一般方法是使用每个租户连接池或每个共享相同数据库但使用不同架构的租户使用单个连接池。

下面是用于切换到多个租户的两个实现-

    public class TestDataSourceBasedMultiTenantConnectionProviderImpl
extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {

    private static final long serialVersionUID = 14535345L;

    @Autowired
    private DataSource defaultDataSource;

    @Autowired
    private TestDataSourceLookup dataSourceLookup;

    /**
     * 
     * Select datasources in situations where not tenantId is used (e.g. startup
     * processing).
     * 
     */
    @Override
    protected DataSource selectAnyDataSource() {
        //logger.trace("Select any dataSource: " + defaultDataSource);
        return defaultDataSource;
    }

    /**
     * 
     * Obtains a DataSource based on tenantId
     * 
     */

    @Override
    protected DataSource selectDataSource(String tenantIdentifier) {

        DataSource ds = dataSourceLookup.getDataSource(tenantIdentifier);
    //  logger.trace("Select dataSource from " + tenantIdentifier + ": " + ds);
        return ds;

    }

import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.springframework.beans.factory.annotation.Autowired;

public class TestCurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver  {

    @Autowired
    private RequestContext context;

    @Override
    public String resolveCurrentTenantIdentifier() {
        // TODO Auto-generated method stub
        return context.getTenantID();
    }

    @Override
    public boolean validateExistingCurrentSessions() {
        // TODO Auto-generated method stub
        return true;
    }

}

答案 1 :(得分:0)

确实,AbstractRouting是一种实现方法。您可以将该方法与请求中的标头混合使用,以轻松实现多租户。 实际上,Baeldung上另一篇文章中提供的链接确实提供了使用这种构造的解决方案。

为每个租户共享和部署一个单独的微服务,并在其前面提供路由服务,这将是另一种服务,我认为它从编码(无需线程本地或其他类似的困难构造)中提供了很多好处。维护角度(您可以在租户级别降低维护/定制服务),因此在特定情况下(假设业务需求允许),这将是我的首选解决方案。

还是,最好的解决方案取决于您的具体情况。

与问题标题相关的最简单解决方案(对于不一定关心多租户的读者)将是在Spring的@Configuration bean中创建多个dataSource实例,并将其放入{{1} },然后将该Map<Integer, DataSource>对象作为Bean返回。当您必须访问它们时,可以访问创建的Map<Integer, DataSource> bean,然后创建Map或类似的资源,并在构造函数中传递特定的NamedParameterJdbcTemplate

伪代码示例:

DataSource