Haorong Mall 多租户使用指南
本文档详细介绍了 haorong-mall 项目中多租户架构的实现原理及使用方法。
1. 架构概述
本项目采用 共享数据库,共享 Schema,字段隔离 的多租户模式。
- 核心字段:所有需要多租户隔离的数据库表必须包含
tenant_id字段。 - 实现技术:基于 MyBatis Plus 的
TenantLineHandler插件实现 SQL 层面的自动拦截与过滤。 - 上下文管理:使用
TransmittableThreadLocal在线程间传递租户信息。
2. 核心组件
2.1 租户上下文 (HxTenantContextHolder)
位于 com.haorong.cloud.common.myabtis.tenant 包下。
- 用于存储当前请求的租户 ID。
- 提供
setTenantId(),getTenantId(),removeTenantId()静态方法。
2.2 租户过滤器 (HxTenantContextFilter)
位于 com.haorong.cloud.common.myabtis.tenant 包下。
- 逻辑:
- 优先获取请求头中的
tenant-id。 - 如果用户已登录:
- 平台管理员(Tenant ID:
平台租户ID):如果请求头指定了tenant-id,则切换到该租户(模拟租户视角);否则使用管理员自己的租户 ID。 - 普通用户:强制使用用户登录信息中的
tenant_id。
- 平台管理员(Tenant ID:
- 如果用户未登录:使用请求头中的
tenant-id。
- 优先获取请求头中的
2.3 MyBatis Plus 拦截器 (HxTenantLineHandler)
位于 com.haorong.cloud.common.myabtis.tenant 包下。
- 自动注入:在执行 SQL 时,自动在
WHERE子句中添加tenant_id = '当前租户ID'。 - 白名单机制:只有在配置中明确指定的表才会启用多租户隔离(详见配置说明)。
3. 开发指南
3.1 新增业务表
如果你创建了一个新的业务表,并希望它支持多租户隔离,请遵循以下步骤:
数据库设计: 在表中添加
tenant_id字段(通常为varchar(32))。配置白名单: 在
application.yml或 Nacos 配置中的hx.tenant.tables列表下添加该表名。yamlhx: tenant: tables: - sys_user - sys_role - your_new_table_name # 添加你的新表注意:本项目采用白名单机制。如果表名不在
hx.tenant.tables中,默认不进行多租户隔离。代码开发:
- 查询:编写 MyBatis Mapper 或 Service 时,不需要手动在 SQL 中写
WHERE tenant_id = ...。插件会自动处理。 - 插入:插入数据时,MyBatis Plus 也会尝试自动填充
tenant_id(需确保实体类字段填充策略配置正确,或由业务逻辑保证)。 - 手动获取 ID:如果在 Service 层需要获取当前租户 ID,请调用:java
String tenantId = HxTenantContextHolder.getTenantId();
- 查询:编写 MyBatis Mapper 或 Service 时,不需要手动在 SQL 中写
4. 租户管理功能
系统内置了完整的租户管理功能(haorong-upms 模块):
- 租户注册:
SysTenantController.register- 注册时会自动创建:管理员角色、根部门、管理员用户。
- 根据选定的 租户套餐 (
SysTenantPackage) 分配初始菜单权限。
- 租户套餐:定义不同等级租户拥有的菜单权限集合。
5. 常见问题
Q: 为什么我的查询没有自动过滤租户数据? A: 请检查 application.yml 中的 hx.tenant.tables 配置,确认你的表名是否已加入白名单。
Q: 平台管理员如何查看特定租户的数据? A: 平台管理员登录后,在请求 Header 中放入目标租户的 ID (tenant-id: target_tenant_id),后端过滤器会自动识别并切换上下文。