gf
gf copied to clipboard
feature(database/gdb): Implement Row-Level Multi-Tenancy Support
gdb目前支持分库分表级别的多租户,补充一个行级多租户的实现
主要特性:
-
租户上下文管理:
- 提供
WithTenantIdField和WithTenantIdValue函数用于设置租户字段名和值到上下文中 - 默认实现
DefaultGetTenantIdFieldValue从上下文中获取租户信息
- 提供
-
模型级租户支持:
- 在Model中添加
Tenant()方法启用多租户功能 - 支持通过
UnTenant()方法禁用多租户功能 TenantOption可配置选项包括:Enable: 控制是否启用租户功能PropagateToJoins: 控制是否将租户条件应用于连接表GetTenantIdFieldValueFunc: 自定义获取租户ID字段和值的函数
- 在Model中添加
-
智能租户条件生成:
- 自动识别单表、JOIN表和逗号分隔的多表查询
- 根据表结构检查租户字段是否存在
- 支持多种租户值类型:
- 基本类型(BaseType):使用等值匹配
- 数组或切片类型(ArrayOrSliceType):使用IN条件
- 空值类型(NullType):使用IS NULL条件
-
无缝集成:
- 租户条件会自动附加到所有查询语句中
- 与现有的软删除、WHERE条件等功能协同工作
- 不影响原有API使用方式
-
注意事项:
WithTenantIdField设置的tenantIdField在构建过程中会检查对应的表字段中有没有这个字段,所以最好是多表的租户字段都相同,如果有需要我也可以加个配置让大家在不同表映射成不同的字段,看大家有没有需求
使用示例:
// 启用租户功能
ctx := WithTenantIdField(context.Background(), "tenant_id")
ctx = WithTenantIdValue(ctx, 1)
// 查询时自动添加租户条件
db.Model("user").Ctx(ctx).Tenant().All()
// 对于JOIN查询,可选择是否传播到连接表
db.Model("user u").
LeftJoin("order o", "u.id=o.user_id").
Ctx(ctx).
Tenant(TenantOption{
Enable: true,
PropagateToJoins: true,
}).
All()
sql
SELECT * FROM user WHERE tenant_id = 1
SELECT * FROM user u LEFT JOIN order o ON u.id=o.user_id WHERE u.tenant_id = 1 AND o.tenant_id = 1