📄 系统多租户使用
内部资料,请刷新扫码登录
pigcloud
版本说明
本文档适合 PIGX V5.9+ 版本,低版本请查看 pigx-tenant-old
# 租户操作
# 新增租户
通过系统管理 > 租户管理功能可以新增租户。新增租户后,需要维护租户人员信息,并进行强刷操作切换到目标租户。
- 新增租户:在租户管理页面点击"新增"按钮,填写租户基本信息
- 维护租户人员:为新增的租户配置管理员和相关用户
- 强刷系统:重新加载租户配置信息
- 切换租户:在前端界面切换到目标租户进行操作
# 使用方法
PigX 多租户实现方式
- 多个租户共享同一个数据库(Database)和模式(Schema)
- 通过表中的 TenantID 字段区分不同租户的数据
- 系统会自动维护租户 ID,开发时无需手动处理
# 1. 数据表配置
在需要支持多租户的表中添加 tenant_id
字段:
# 2. 租户隔离配置
有两种配置方式:
# 方式一:使用注解(v5.4+)
在实体类上添加注解:
@TenantTable
# 方式二:YAML 配置
在对应微服务的 nacos 配置中添加:
pigx:
tenant:
column: tenant_id # 租户ID字段名
tables: # 需要进行租户隔离的表
- sys_user
# 高级用法
# 手动切换租户
注意事项
禁止在实体对象中直接设置 tenant 字段,这会导致错误
正确的切换方式是使用 TenantContextHolder:
// 手动设置租户ID(在查询前调用)
TenantContextHolder.setTenantId(1); // 切换到租户ID为1的数据
// 执行查询操作,此时强制查询到租户ID为1的用户数据
List<User> users = baseMapper.selectList(null);
# 跳过租户过滤
在需要查询所有租户数据时:
// 跳过租户过滤,查询所有租户的数据
TenantContextHolder.setTenantSkip();
// 执行查询操作,此时会查询所有租户的用户数据
List<User> allUsers = baseMapper.selectList(null);
示例:
# 技术实现原理
系统基于 MyBatis-Plus 的多租户 SQL 解析器 (opens new window)实现,主要包含:
# 1. 租户 ID 传递
通过全局过滤器获取并存储租户 ID:
public class TenantContextHolderFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
// 从请求头获取租户ID
String tenantId = request.getHeader(CommonConstants.TENANT_ID);
// 设置租户上下文
if (StrUtil.isNotBlank(tenantId)) {
TenantContextHolder.setTenantId(Integer.parseInt(tenantId));
} else {
TenantContextHolder.setTenantId(CommonConstants.TENANT_ID_1);
}
filterChain.doFilter(request, response);
TenantContextHolder.clear();
}
}
# 2. 跨线程租户信息传递
使用阿里巴巴的 TransmittableThreadLocal 实现:
public class TenantContextHolder {
private final ThreadLocal<Integer> THREAD_LOCAL_TENANT = new TransmittableThreadLocal<>();
}