gpt4 book ai didi

java - 如何实现 Multi-Tenancy Spring Boot 应用程序(每个用户都有自己的数据库)

转载 作者:行者123 更新时间:2023-12-04 01:10:43 24 4
gpt4 key购买 nike

我正在使用 spring boot 构建一个 REST-API,我想实现一个 Multi-Tenancy 结构来处理数据。
我想要一个名为 Main 的数据库这将有 User表,该表将包含有关用户的数据(用户名、密码 ... 和一个字段 database,它将表示为该用户指定了哪个数据库)。
每次用户注册时,都会创建他各自的数据库(这是我面临的困难之一)。
我已经阅读了不同的教程,它们都带有预定义的 Datasource s 在 application.properties文件。显然这里不是这种情况,因为每个用户的数据库将“动态”创建,或者如果它已经创建则访问它。
工作流程是这样的(解释尽可能简单):

  • 用户注册
  • 应用程序创建用户实体并将其保存到 Main DB 并为用户
  • 创建相应的 DB
  • 如果用户通过了身份验证,应用程序会检查每个调用,如果是,则从他的 DB
  • 中获取数据

    然后有很多关于在自动创建数据库时填充数据库的问题。
    但首先要做的事情是:)
    我的堆栈:POSTGRESQL,Spring Boot
    先感谢您。

    最佳答案

    可以通过以下步骤根据您的需要实现 Multi-Tenancy 。

  • 添加2个配置类,一个用于共享数据库,一个用于租户数据库,配置LocalContainerEntityManagerFactoryBean。此 bean 应该为 LocalContainerEntityManagerFactoryBean 设置所需的 Multi-Tenancy 属性
    例如
  •  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");
    这个类还应该为每种类型实现命名的 bean transactionManager。例如
     @Bean(name = "tenantTransactionManager")
    public PlatformTransactionManager transactionManager() {
    JpaTransactionManager tm = new JpaTransactionManager();
    tm.setEntityManagerFactory(this.entityManagerFactory().getObject());
    return tm;
    }

  • 实现接口(interface) CurrentTenantIdentifierResolver 和方法 resolveCurrentTenantIdentifier。这应该根据当前登录的用户返回租户的数据库名称。如果没有用户登录,则为默认数据库名称
  • 用于记住当前租户名称的线程安全上下文持有者
  • 使用 @Transactional 注释为实体类的服务实现进行注释,并传递适当实体管理器的 bean 名称,例如
  • @Transactional("tenantTransactionManager") // for tenant database
    @Transactional("transactionManager") // for shared database.

  • 在新用户注册时设置数据库模式创建方法。并将租户数据库名称维护为共享模式中用户表中的列之一。
  • 如果您使用的是 Spring Security,请实现 UserDetailsS​​ervice 接口(interface)并实现方法 loadUserByUsername,以便它返回 TenantUser 类的对象,该对象包含用户登录的附加信息(租户数据库名称)。
  • public class TenantUser extends org.springframework.security.core.userdetails.User {


    /** The tenand id. */
    private String tenantId;
    希望这些步骤可以帮助您实现您想要的。有许多文章详细解释了所有这些步骤。我的实现深深嵌入我的项目中,因此它不处于可以作为工作示例共享的状态。
    很高兴回答任何进一步的问题

    关于java - 如何实现 Multi-Tenancy Spring Boot 应用程序(每个用户都有自己的数据库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64945839/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com