系统多租户使用
租户操作
新增租户
通过系统管理 > 租户管理功能可以新增租户。新增租户后,需要维护租户人员信息,并进行强刷操作切换到目标租户。
💡操作流程
新增租户后需要完成人员配置和系统强刷,才能正常使用新租户功能。
- 新增租户:在租户管理页面点击"新增"按钮,填写租户基本信息
- 维护租户人员:为新增的租户配置管理员和相关用户
- 强刷系统:重新加载租户配置信息
- 切换租户:在前端界面切换到目标租户进行操作
使用方法
⚠多租户实现方式
多个租户共享同一个数据库(Database)和模式(Schema
通过表中的 TenantID 字段区分不同租户的数据
系统会自动维护租户 ID,开发时无需手动处理
数据表配置
在需要支持多租户的表中添加 tenant_id 字段:
租户隔离配置
有两种配置方式:
高级用法
手动切换租户
⛔禁止直接设置
禁止在实体对象中直接设置 tenant 字段,这会导致错误。正确的切换方式是使用 TenantContextHolder。
// 手动设置租户ID(在查询前调用)
TenantContextHolder.setTenantId(1); // 切换到租户ID为1的数据
// 执行查询操作,此时强制查询到租户ID为1的用户数据
List<User> users = baseMapper.selectList(null);
跳过租户过滤
在需要查询所有租户数据时:
// 跳过租户过滤,查询所有租户的数据
TenantContextHolder.setTenantSkip();
// 执行查询操作,此时会查询所有租户的用户数据
List<User> allUsers = baseMapper.selectList(null);
示例:
关闭多租户功能
在 PIGX 中,多租户是一个"按需使用"的能力,如果业务不需要租户,默认也不会影响系统运行。
系统的多租户逻辑依赖三部分:前端的租户选择、HTTP Header 中的租户标识、数据库字段 tenant_id。因此,只要关闭前端入口或数据库不包含 tenant 字段,就不会触发多租户隔离行为。
前端关闭(推荐)
✓推荐方式
适用于:业务只有一个租户,但未来可能会扩展,保留扩展空间。
当前端不展示"租户管理""租户切换"等菜单时:
- 用户不会主动切换租户
- 前端不会传递 TENANT_ID
- 服务端自动使用默认租户(一般为租户 ID 1)
前端屏蔽方式
- 在权限管理菜单中隐藏租户管理页面
- 在系统顶部导航中隐藏租户切换入口
- 删除或隐藏相关按钮即可,无需改动服务端代码
技术实现原理
系统基于 MyBatis-Plus 的多租户 SQL 解析器实现,主要包含:
租户 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();
}
}
跨线程租户信息传递
使用阿里巴巴的 TransmittableThreadLocal 实现:
public class TenantContextHolder {
private final ThreadLocal<Integer> THREAD_LOCAL_TENANT = new TransmittableThreadLocal<>();
}