栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

多租户:使用Spring Data JPA管理多个数据源

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多租户:使用Spring Data JPA管理多个数据源

为了使用Spring
Boot实现多租户,我们可以将AbstractRoutingDataSource用作所有“
租户数据库 ”的基础 DataSource 类。 __

它有一个抽象方法determineCurrentLookupKey我们必须重写。它告诉您当前必须使用

AbstractRoutingDataSource
哪个租户数据源。因为它在多线程环境中工作,所以所选租户的信息应存储在
ThreadLocal
变量中。

AbstractRoutingDataSource
租户数据源的信息存储在其private中
Map<Object, Object>targetDataSources
。该映射的键是 租户标识符 (例如String类型)和值- 租户数据源
。要将租户数据源放入此地图,我们必须使用其setter
setTargetDataSources

如果

AbstractRoutingDataSource
没有必须使用method设置的“默认”数据源,则无法使用
setDefaultTargetDataSource(ObjectdefaultTargetDataSource)

设置租户数据源和默认数据源后,我们必须调用方法

afterPropertiesSet()
来告知
AbstractRoutingDataSource
来更新其状态。

所以我们的“ MultiTenantManager”类可以像这样:

@Configurationpublic class MultiTenantManager {    private final ThreadLocal<String> currentTenant = new ThreadLocal<>();    private final Map<Object, Object> tenantDataSources = new ConcurrentHashMap<>();    private final DataSourceProperties properties;    private AbstractRoutingDataSource multiTenantDataSource;    public MultiTenantManager(DataSourceProperties properties) {        this.properties = properties;    }    @Bean    public DataSource dataSource() {        multiTenantDataSource = new AbstractRoutingDataSource() { @Override protected Object determineCurrentLookupKey() {     return currentTenant.get(); }        };        multiTenantDataSource.setTargetDataSources(tenantDataSources);        multiTenantDataSource.setDefaultTargetDataSource(defaultDataSource());        multiTenantDataSource.afterPropertiesSet();        return multiTenantDataSource;    }    public void addTenant(String tenantId, String url, String username, String password) throws SQLException {        DataSource dataSource = DataSourceBuilder.create()     .driverClassName(properties.getDriverClassName())     .url(url)     .username(username)     .password(password)     .build();        // Check that new connection is 'live'. If not - throw exception        try(Connection c = dataSource.getConnection()) { tenantDataSources.put(tenantId, dataSource); multiTenantDataSource.afterPropertiesSet();        }    }    public void setCurrentTenant(String tenantId) {        currentTenant.set(tenantId);    }    private DriverManagerDataSource defaultDataSource() {        DriverManagerDataSource defaultDataSource = new DriverManagerDataSource();        defaultDataSource.setDriverClassName("org.h2.Driver");        defaultDataSource.setUrl("jdbc:h2:mem:default");        defaultDataSource.setUsername("default");        defaultDataSource.setPassword("default");        return defaultDataSource;    }}

简要说明:

  • 映射

    tenantDataSources
    它是我们放置到
    setTargetDataSources
    设置程序中的本地租户数据源存储;

  • DataSourceProperties properties
    用于从
    spring.datasource.driverClassName
    ‘application.properties’ 的租户数据库获取数据库驱动程序类名称(例如
    org.postgresql.Driver
    );

  • 方法

    addTenant
    用于将新的租户及其数据源添加到我们的本地租户数据源存储中。有了这种方法, 我们可以快速做到
    afterPropertiesSet()
    ;

  • 方法

    setCurrentTenant(String tenantId)
    用于“切换”到给定租户的数据源。例如,在处理使用数据库的请求时,我们可以在REST控制器中使用此方法。该请求应包含“ tenantId”,例如在
    X-TenantId
    标头中,我们可以检索并放入此方法;

  • defaultDataSource()
    是使用内存中的H2数据库构建的,以避免在运行的SQL Server上使用默认数据库。

注意: 必须

spring.jpa.hibernate.ddl-auto
参数设置为,
none
以禁用Hibernate在数据库模式中进行更改。您必须事先创建租户数据库的架构。

此类的完整示例,您可以在我的 仓库中
找到更多示例。

更新

该分支演示了一个使用专用数据库存储租户数据库属性而不是属性文件的示例(请参见下面的@MarcoGustavo问题)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/365791.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号