具有共享数据库和鉴别器列的多租户

问题描述 投票:0回答:2

Hibernate 多租户共享数据库(鉴别器列)到目前为止仍未实现。

我正在开发 Quarkus RestEasy JAX-RS 端点。 我想使用多租户架构(不是单独的数据库或单独的模式,而是带有判别器列(如tenantId)的共享数据库)。 Quarkus 也只支持单独的数据库和单独的模式,如 Hibernate。

那么,如何实现自定义解析器来根据tenantId编写端点资源方法(get、post、put、delete)?

我想过拦截器或过滤器,但我不知道如何用 Quarkus 实现它。

这个想法是(SaaS):

  • 创建客户帐户(为其设置租户ID)
  • 用户登录时,根据其tenantId获取数据。

用例:

Tenant1发送包含其tenantId的HTTP请求,从端点资源中获取tenantId,并根据当前tenantId值实现save()、getAll()、get()、delete()方法,因此每个租户只会获取或添加他自己的数据。

其他可能性:

是否可以使用单独的模式并编写一个可以从所有租户模式中获取数据的服务(管理器仪表板)?

示例:

  • 租户1 = StackOverflow US(员工数量 = 50)(架构 1 中的员工表)

  • 租户2 = StackOverflow France(员工数量 = 30)(SCHEMA 2 中的员工表)

  • StackOverFlow Global Manager Dashboard(员工总数= 80,Schema 1员工表Schema 2员工表的总和),他还可以按子公司进行统计。

java database rest multi-tenant quarkus
2个回答
0
投票

Quarkus 目前仅支持单独的数据库和单独的多租户架构,请参阅 https://quarkus.io/guides/hibernate-orm#multitenancy

您想要的是分区(鉴别器)数据,请参阅https://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/ch16.html#d5e4808

因此,如果您可以使用单独的模式,则可以使用 Quarkus 进行 OOTB。

对于全局仪表板,您可以在专用模式上创建一个视图,该模式是“按租户”模式上相应表的并集。


0
投票

在 Quarkus 3 中,Hibernate 6.0 引入了一个名为

@TenantId
的新功能,该功能有助于根据特定列(鉴别器)分隔租户。要在 Quarkus 中使用此功能,您需要实现一个
TenantResolver
接口。该接口包括一个名为
resolveTenantId
的方法,您需要设计一个逻辑来从传入请求中提取租户 ID 并将其返回。然后,
@TenantId
注释将利用此租户 ID 来进行过滤。使用
@TenantId
时,应将其放置在您打算用于过滤的列上

import jakarta.enterprise.context.ApplicationScoped;

import io.quarkus.hibernate.orm.runtime.tenant.TenantResolver;
import io.vertx.ext.web.RoutingContext;

@PersistenceUnitExtension 
@RequestScoped 
public class CustomTenantResolver implements TenantResolver {

    @Inject
    RoutingContext context;

    @Override
    public String getDefaultTenantId() {
        return "base";
    }

    @Override
    public String resolveTenantId() {
        String path = context.request().path();
        String[] parts = path.split("/");

        if (parts.length == 0) {
            // resolve to default tenant config
            return getDefaultTenantId();
        }

        return parts[1];
    }

}


@MappedSuperclass
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public abstract class AbstractBaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Size(max = 30)
    @Column(name = "tenant_id")
    @TenantId
    private String tenantId;

}

创建一个像上面这样的基本实体并使用,最好在所有实体中复制代码

© www.soinside.com 2019 - 2024. All rights reserved.