我在业务中必须解决以下问题。我正在使用Spring
进行项目开发,我要连接8个数据源。
将要求告知合同编号,通过此联系电话,我必须选择8个数据源之一并进行客户咨询。
示例:
我有基本的Brazil = 1
,Spain = 2
和Germany = 3
id = 1
,则应该从Brazil base
获取客户数据。id = 2
,则应获取客户数据
来自Spain base
。id = 3
,则应该从Germany base
获取客户数据。如果使用multitenancy
或AbstractRouting
,我不知道如何解决此问题。而且我不知道如何为此启动代码。
会有人提供任何解决方案和示例吗?
答案 0 :(得分:1)
Spring可以使用AbstractRoutingDataSource
动态确定数据源。但是需要使用ThreadLocal
将上下文绑定到当前线程。
如果您生成多个线程或在应用程序中使用异步,这可能会使事情复杂化。
您可以参考简单的范例here
如果您确实需要根据不同的客户端创建数据库连接,则hibernate提供了一种管理Multi-tenancy
,Hibernate 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