mysql - Spring boot multitenancy ,其中一个租户连接到多个模式
问题描述
我正在创建一个 Spring Boot 应用程序,它应该支持多租户、单独的数据库方法。每个租户都将使用多个架构,并且将从某个配置文件动态加载。租户和模式将是这样的,
租户 1:
url : dbc:mysql://dns1/abc_schema
username : sa
password : sa
url : dbc:mysql://dns1/pqr_schema
username : sa
password : sa
url : dbc:mysql://dns1/xyz_schema
username : sa
password : sa
租户 2:
url : dbc:mysql://dns2/abc_schema
username : sa
password : sa
url : dbc:mysql://dns2/pqr_schema
username : sa
password : sa
url : dbc:mysql://dns2/xyz_schema
username : sa
password : sa
目前它是一个单租户应用程序,其中所有 3 个模式都在 application.properties 中提到。所有数据库实例具有相同的模式名称,但在不同的数据库实例中。现在,有 3 个带有 @ 配置的单独配置文件用于在应用程序启动时加载表。
我正在将此应用程序转换为多租户应用程序。使用具有单个架构的租户实现多租户应用程序的步骤很清楚,但我有多个租户架构。所以,问题是在实现 AbstractDataSourceBasedMultiTenantConnectionProviderImpl
类时,selectDataSource()
函数返回单个数据源。但是如何传递其中的多个模式呢?
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
if (isInitialLoad) {
isInitialLoad = false;
TenantDataSource tenantDataSource = context.getBean(TenantDataSource.class);
map.putAll(tenantDataSource.getAll());
}
return map.get(tenantIdentifier);
}
提前致谢, 谢尔茨
解决方案
这只是给出的方法并不完全是解决方案
如下所示定义路由器,然后您可以在配置中设置
public class ClientDataSourceRouter
extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return ClientDatabaseContextHolder.getClientDatabase();
}
}
我们需要一个上下文映射到 DataSource 对象来配置我们的 AbstractRoutingDataSource。如果没有设置上下文,我们还可以指定要使用的默认 DataSource。
我们使用的数据源可以来自任何地方,但通常会在运行时创建或使用 JNDI 查找:
@Configuration 公共类 RoutingTestConfiguration {
@Bean
public DataSource clientDatasource() {
Map<Object, Object> targetDataSources = new HashMap<>();
DataSource clientADatasource = clientADatasource();
DataSource clientBDatasource = clientBDatasource();
targetDataSources.put(ClientDatabase.CLIENT_A,
clientADatasource);
targetDataSources.put(ClientDatabase.CLIENT_B,
clientBDatasource);
ClientDataSourceRouter clientRoutingDatasource
= new ClientDataSourceRouter();
clientRoutingDatasource.setTargetDataSources(targetDataSources);
clientRoutingDatasource.setDefaultTargetDataSource(clientADatasource);
return clientRoutingDatasource;
}
// ...
}
另一种解决方案定义如下
多租户模型 有几种模型可以在应用程序中实现多租户:
- 每个租户的数据库 每个租户都有自己的数据库,并且与其他租户隔离。
- 共享数据库,独立架构(这就是我们要找的)
所有租户共享一个数据库,但有自己的数据库模式和自己的表。
- Shared Database, Shared Schema 所有租户共享一个数据库和表。每个表都有一个带有租户标识符的列,它显示了该行的所有者。
例子 :
@Bean
public DataSource dataSource() {
AbstractRoutingDataSource dataSource = new TenantAwareRoutingSource();
Map<Object,Object> targetDataSources = new HashMap<>();
targetDataSources.put("TenantOne", tenantOne());
targetDataSources.put("TenantTwo", tenantTwo());
dataSource.setTargetDataSources(targetDataSources);
dataSource.afterPropertiesSet();
return dataSource;
}
public DataSource tenantOne() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setInitializationFailTimeout(0);
dataSource.setMaximumPoolSize(5);
dataSource.setDataSourceClassName("org.postgresql.ds.PGSimpleDataSource");
dataSource.addDataSourceProperty("url", "jdbc:postgresql://127.0.0.1:5432/sampledb");
dataSource.addDataSourceProperty("user", "philipp");
dataSource.addDataSourceProperty("password", "test_pwd");
**we need to find datasource.setschema is exist or not**
return dataSource;
}
public DataSource tenantTwo() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setInitializationFailTimeout(0);
dataSource.setMaximumPoolSize(5);
dataSource.setDataSourceClassName("org.postgresql.ds.PGSimpleDataSource");
dataSource.addDataSourceProperty("url", "jdbc:postgresql://127.0.0.1:5432/sampledb1");
dataSource.addDataSourceProperty("user", "philipp");
dataSource.addDataSourceProperty("password", "test_pwd");
** we need to find datasource.setschema is exist or not**
return dataSource;
}
或者只有一个选项也存在
租户一
spring.datasource.first.url=jdbc:postgresql://my_url:my_port/my_other_stuff
spring.datasource.first.username=my_user_name
spring.datasource.first.password=my_password
spring.datasource.first.driver-class-name=org.postgresql.Driver
spring.datasource.first.schema=A
租户二
spring.source.second.url=jdbc:postgresql://my_url:my_port/my_other_stuff
spring.source.second.username=my_user_name
spring.source.second.password=my_password
spring.source.second.driver-class-name=org.postgresql.Driver
spring.source.second.schema = B
然后为每个创建 PropertySource 类,然后它将由 spring 设置,之后您可以使用它们
@ConfigurationProperties(prefix = "datasource.first")
@Bean
@Primary
public DataSource dataSource() {
return DataSourceBuilder
.create()
.build();
}
还要检查此链接 在此处输入链接描述
推荐阅读
- r - tableone 包:如何从 svydesign 对象中获取优势比和置信区间?
- javascript - 在 API 调用和更改状态后,React 不会重新渲染
- java - 以二进制数计算 0 的序列
- javascript - 验证文本字段中的字符
- flutter - 使用 in_app_purchases 的 Flutter 应用程序,在投入生产之前要做什么?
- linux - 在 Linux 20.04 上安装 GDAL 扩展和 GDAL 后 GeoServer 2.19.2 ECW、MrSid、JP2 商店不存在
- android - 当我更改元素的 id 时,通过 ConstraintSet 以编程方式添加障碍不起作用?
- python - 如何使用 numpy 优雅地生成这种稀疏模式?
- python-3.x - Cleaned_data 以 django 形式作为空数据出现?
- javascript - 如何将多个字符串合并为一个字符串