如何在Hibernate中为多租户配置多个数据源

如何在Hibernate中为多租户配置多个数据源,hibernate,spring,multi-tenant,Hibernate,Spring,Multi Tenant,我正在尝试使用单独的模式方法将多租户添加到java应用程序中,如中所述 我想知道如何通过spring配置多个数据源,可能是通过使用属性文件,并根据租户id从spring上下文获取数据源 更重要的是,尽管我希望能够配置支持此多租户功能的自定义连接提供程序实现,以供Hibernate使用,而不是它默认使用的注入式ConnectionProvider 如何实现这一点。使用AbstractRoutingDataSource。请参阅位于@。的我的答案。这篇文章演示了如何使用spring security和

我正在尝试使用单独的模式方法将多租户添加到java应用程序中,如中所述

我想知道如何通过spring配置多个数据源,可能是通过使用属性文件,并根据租户id从spring上下文获取数据源

更重要的是,尽管我希望能够配置支持此多租户功能的自定义连接提供程序实现,以供Hibernate使用,而不是它默认使用的注入式
ConnectionProvider


如何实现这一点。

使用
AbstractRoutingDataSource
。请参阅位于@。

的我的答案。这篇文章演示了如何使用spring security和AbstractRoutingDataSource构建多租户SaaS应用程序

如果要通过
ConnectionProvider
执行多租户,则需要一个本地线程来提供上下文。请参阅本简介:


路由可由Hibernate通过its完成,您可以这样实现:

public class MultiTenantConnectionProvider
        extends AbstractMultiTenantConnectionProvider {
 
    public static final MultiTenantConnectionProvider INSTANCE =
            new MultiTenantConnectionProvider();
 
    private final Map<String, ConnectionProvider> connectionProviderMap = 
            new HashMap<>();
 
    Map<String, ConnectionProvider> getConnectionProviderMap() {
        return connectionProviderMap;
    }
 
    @Override
    protected ConnectionProvider getAnyConnectionProvider() {
        return connectionProviderMap.get(
            TenantContext.DEFAULT_TENANT_IDENTIFIER
        );
    }
 
    @Override
    protected ConnectionProvider selectConnectionProvider(
            String tenantIdentifier) {
        return connectionProviderMap.get(
            tenantIdentifier
        );
    }
}
您可以为管理相关任务注册默认租户:

addTenantConnectionProvider(
    TenantContext.DEFAULT_TENANT_IDENTIFIER, 
    defaultDataSource, 
    properties()
);
对于实际租户,您可以使用如下方法:

private void addTenantConnectionProvider(
        String tenantId, 
        DataSource tenantDataSource, 
        Properties properties) {
         
    DatasourceConnectionProviderImpl connectionProvider = 
        new DatasourceConnectionProviderImpl();
    connectionProvider.setDataSource(tenantDataSource);
    connectionProvider.configure(properties);
     
    MultiTenantConnectionProvider.INSTANCE
    .getConnectionProviderMap()
    .put(
        tenantId, 
        connectionProvider
    );
}
private void addTenantConnectionProvider(
        String tenantId) {
     
    DataSourceProvider dataSourceProvider = database()
    .dataSourceProvider();
 
    Properties properties = properties();
 
    MysqlDataSource tenantDataSource = new MysqlDataSource();
    tenantDataSource.setDatabaseName(tenantId);
    tenantDataSource.setUser(dataSourceProvider.username());
    tenantDataSource.setPassword(dataSourceProvider.password());
 
    properties.put(
        Environment.DATASOURCE,
        dataSourceProxyType().dataSource(tenantDataSource)
    );
 
    addTenantConnectionProvider(
        tenantId, 
        tenantDataSource, 
        properties
    );
}
您可以将
MysqlDataSource
更改为您正在使用的任何数据库

那么,登记租户就这么简单了:

addTenantConnectionProvider("asia");
addTenantConnectionProvider("europe");
最后要考虑的是通过
Hibernate.multi_-tenant\u-connection\u-provider
配置属性向Hibernate提供
multi-tenacyconnectionprovider
实现

properties.put(
    AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, 
    MultiTenantConnectionProvider.INSTANCE
);