跳到主要内容
版本:0.3.x(Latest)

基本介绍

TenantFilterService为插件提供数据库查询的租户过滤注入能力。插件通过services.TenantFilter()获取该服务,用于为插件自有表追加tenant_id过滤条件,实现多租户数据隔离。

该服务是源码插件独有能力,不在capability.Services中暴露,而是通过pluginhost.Services扩展提供。这是因为TenantFilterService携带数据库查询构建器(*gdb.Model),按照能力服务的设计原则,这类能力不通过普通capability.Services暴露。

设计思路

TenantFilterService采用查询注入模式:插件将数据库查询模型传入Apply方法,服务自动追加tenant_id条件,返回修改后的查询模型。

Apply方法的qualifier参数用于指定表名或别名,适用于联合查询场景:

qualifier值说明
空字符串tenant_id列不加表限定符
表名tenant_id列加表限定符,如my_table.tenant_id
别名tenant_id列加别名限定符,如t.tenant_id

Context方法返回TenantFilterContext,包含当前请求的租户、用户、模拟状态等信息,供插件在需要手动构建查询条件时使用。

架构位置

TenantFilterService在插件数据访问层被广泛使用:

几乎所有租户感知的插件都会使用该服务。典型模式是在DAO层的查询方法中调用Apply,确保所有数据访问都经过租户过滤。

与pluginhost.Services的关系

TenantFilterServicepluginhost.Services扩展的能力,不在capability.Services中。 这样设计的原因是TenantFilterService的方法携带*gdb.Model数据库查询构建器。按照能力服务的设计原则,涉及数据库查询构建器的能力不通过普通capability.Services暴露,以防止普通消费接口泄露数据库细节。

主要能力

方法说明
Context返回当前请求的TenantFilterContext,包含租户、用户、模拟状态等信息
Apply向查询模型追加tenant_id过滤条件,PlatformBypass时跳过过滤

设计约束

  • 源码插件独有。 TenantFilterService不通过capability.Services暴露,动态插件通过hostServices授权机制访问等价能力。
  • PlatformBypass自动跳过。 当请求运行在平台范围(TenantID = 0)时,Apply自动跳过租户过滤,允许跨租户读取。
  • 插件不应手写租户过滤。 使用TenantFilterService而非手写WHERE tenant_id = ?,确保过滤逻辑与宿主的平台绕过、模拟等策略一致。
  • qualifier用于联合查询。 单表查询通常使用空字符串,联合查询时需要指定表名或别名避免列名歧义。

相关服务

  • BizCtxService - TenantFilterContext中的身份信息来自BizCtx
  • TenantService - 租户能力提供租户解析,TenantFilter使用租户信息过滤数据
  • CacheService - 缓存键中的租户隔离与TenantFilter的查询过滤互补