refactor: 拆分多租户

This commit is contained in:
Ray.Hao
2025-12-15 08:05:24 +08:00
parent 3f05f77351
commit 5817826bbd
57 changed files with 297 additions and 2291 deletions

View File

@@ -1,22 +0,0 @@
package com.youlai.boot.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 忽略多租户注解
* <p>
* 标注在方法或类上,表示该方法或类下的所有方法忽略多租户过滤
* 适用于系统管理、租户管理等不需要租户隔离的场景
* </p>
*
* @author Ray.Hao
* @since 3.0.0
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreTenant {
}

View File

@@ -13,7 +13,6 @@ import java.time.LocalDateTime;
* 基础实体类
*
* <p>实体类的基类,包含了实体类的公共属性,如创建时间、更新时间、逻辑删除标识等</p>
* <p>多租户模式下,会自动添加 tenant_id 字段(通过 MyMetaObjectHandler 自动填充)</p>
*
* @author Ray
* @since 2024/6/23
@@ -30,26 +29,6 @@ public class BaseEntity implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
/**
* 租户ID多租户模式
* <p>
* 注意:此字段仅在启用多租户时生效
* 通过 MyMetaObjectHandler 自动填充,无需手动设置
* 如果不需要多租户,可以通过配置 youlai.tenant.enabled=false 禁用
* </p>
* <p>
* 重要说明:
* 1. 默认使用 exist = false 标记字段不存在于数据库,避免单租户模式下报错
* 2. 在启用多租户时,需要确保数据库表中有 tenant_id 字段
* 3. 多租户的数据隔离主要通过 TenantLineHandler 自动添加 WHERE 条件实现
* 4. 如果需要在 INSERT 时写入 tenant_id请将 exist 改为 true 或移除 exist 属性
* 5. 或者执行 add_tenant_column.sql 脚本为表添加 tenant_id 字段
* </p>
*/
@TableField(value = "tenant_id", exist = false)
@JsonInclude(value = JsonInclude.Include.NON_NULL)
private Long tenantId;
/**
* 创建时间
*/

View File

@@ -35,11 +35,6 @@ public interface JwtClaimConstants {
*/
String AUTHORITIES = "authorities";
/**
* 租户ID
*/
String TENANT_ID = "tenantId";
/**
* 安全版本号,用于按用户失效历史令牌
*/

View File

@@ -1,83 +0,0 @@
package com.youlai.boot.common.tenant;
import com.alibaba.ttl.TransmittableThreadLocal;
import lombok.extern.slf4j.Slf4j;
/**
* 租户上下文工具类
* <p>
* 使用 TransmittableThreadLocal 存储当前线程的租户ID确保线程安全
* 支持异步任务、线程池、消息队列等场景的上下文传递
* </p>
*
* @author Ray.Hao
* @since 3.0.0
*/
@Slf4j
public class TenantContextHolder {
/**
* 租户ID线程本地变量
* 使用 TransmittableThreadLocal 支持父子线程和线程池场景的值传递
*/
private static final TransmittableThreadLocal<Long> TENANT_ID_HOLDER = new TransmittableThreadLocal<>();
/**
* 忽略租户标志(用于某些场景下临时跳过租户过滤)
*/
private static final TransmittableThreadLocal<Boolean> IGNORE_TENANT_HOLDER = new TransmittableThreadLocal<>();
/**
* 设置当前租户ID
*
* @param tenantId 租户ID
*/
public static void setTenantId(Long tenantId) {
if (tenantId != null) {
TENANT_ID_HOLDER.set(tenantId);
log.debug("设置当前租户ID: {}", tenantId);
}
}
/**
* 获取当前租户ID
*
* @return 租户ID如果未设置则返回 null
*/
public static Long getTenantId() {
return TENANT_ID_HOLDER.get();
}
/**
* 设置忽略租户标志
*
* @param ignore 是否忽略
*/
public static void setIgnoreTenant(boolean ignore) {
IGNORE_TENANT_HOLDER.set(ignore);
log.debug("设置忽略租户标志: {}", ignore);
}
/**
* 是否忽略租户
*
* @return true-忽略false-不忽略
*/
public static boolean isIgnoreTenant() {
Boolean ignore = IGNORE_TENANT_HOLDER.get();
return ignore != null && ignore;
}
/**
* 清除当前线程的租户上下文
* <p>
* 必须在请求结束时调用,避免线程池复用导致的数据泄露
* </p>
*/
public static void clear() {
TENANT_ID_HOLDER.remove();
IGNORE_TENANT_HOLDER.remove();
log.debug("清除租户上下文");
}
}