Ren*_*235 8 java spring multi-tenant spring-data-jpa spring-boot
我正在使用 Spring Boot 构建 REST-API,我想实现一个多租户结构来处理数据。我想要一个名为的数据库,Main该数据库将包含一个User表,该表将包含有关用户的数据(用户名、密码......以及一个表示database指定给该用户的数据库的字段)。每次用户注册时,都会创建他各自的数据库(这是我面临困难的点之一)。我读过不同的教程,它们都Datasource在application.properties文件中预定义了。显然,这里的情况并非如此,因为每个用户的数据库将“即时”创建,或者如果已经创建,则进行访问。
工作流程是这样的(尽可能简单地解释):
Main数据库并为用户创建相应的数据库然后,在自动创建数据库时,会出现很多关于填充数据库的问题。但首先要说的是:)
我的堆栈:POSTGRESQL、Spring Boot
先感谢您。
可以根据您的需要通过以下步骤实现多租户。
Map<String, Object> properties = hibernateProperties.determineHibernateProperties(
this.properties.getProperties(), new HibernateSettings());
properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA);
properties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, this.connectionProvider);
properties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, this.resolver);
properties.put(Environment.DIALECT, "org.hibernate.dialect.MySQLDialect");
Run Code Online (Sandbox Code Playgroud)
该类还应该为每种类型实现命名 bean transactionManager。例如
@Bean(name = "tenantTransactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(this.entityManagerFactory().getObject());
return tm;
}
Run Code Online (Sandbox Code Playgroud)
实现接口CurrentTenantIdentifierResolver和方法resolveCurrentTenantIdentifier。这应该根据当前登录用户返回租户的数据库名称。或者如果没有用户登录则使用默认数据库名称
用于记住当前租户名称的线程安全上下文持有者
使用 @Transactional 注释来注释实体类的服务实现,并传递适当的实体管理器的 bean 名称,例如
@Transactional("tenantTransactionManager") // for tenant database
Run Code Online (Sandbox Code Playgroud)
和
@Transactional("transactionManager") // for shared database.
Run Code Online (Sandbox Code Playgroud)
设置新用户注册时的数据库架构创建方法。并将租户数据库名称维护为共享模式中用户表中的列之一。
如果您使用 Spring Security,请实现 UserDetailsService 接口并实现方法 loadUserByUsername ,以便它返回 TenantUser 类的对象,其中包含用户登录的附加信息(租户数据库名称)。
public class TenantUser extends org.springframework.security.core.userdetails.User {
/** The tenand id. */
private String tenantId;
Run Code Online (Sandbox Code Playgroud)
希望这些步骤可以帮助您实现您想要的目标。有许多文章详细解释了所有这些步骤。我的实现深深嵌入到我的项目中,因此它不处于可以作为工作示例共享的状态。
很高兴回答任何进一步的问题
我在这里找到了问题的完整解决方案:
多租户:使用 Spring Data JPA 管理多个数据源
非常感谢作者@Cepr0。
唯一缺少的是动态创建数据库。当我完成我的实现时,我将在这里更新答案。
更新
我使用以下代码创建了数据库,这是 @Milind Barve 推荐的。所以谢谢。
Class.forName("org.postgresql.Driver");
Connection con = DriverManager.getConnection("jdbc:postgresql://localhost:5432/","postgres", "password");
Statement smt = con.createStatement();
smt.executeUpdate("CREATE DATABASE [name_of_db_here] WITH OWNER DEFAULT");
Run Code Online (Sandbox Code Playgroud)
更新:初始化每个新创建的数据库的架构,我创建了一个包含所有表创建的 .sql 文件,并使用 FlyWay 初始化每个新创建的数据库
// INITIALIZE THE DB
Flyway flyway = Flyway.configure()
.dataSource(dataSource)
.target(MigrationVersion.LATEST)
.load();
flyway.migrate();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12514 次 |
| 最近记录: |