多租户用例-Mybatis-plus

我们可以通过注解+配置实现项目多租户数据隔离

注解定义:


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Tenant {
}
public class TenantContext {
    private static final ThreadLocal<String> TENANT = new ThreadLocal<>();

    public static void setTenant(String tenant) {
        TENANT.set(tenant);
    }

    public static String getTenant() {
        return TENANT.get();
    }

    public static void clear() {
        TENANT.remove();
    }
}

切面配置


import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect @Component
public class TenantAspect { @Autowired private MybatisPlusInterceptor mybatisPlusInterceptor; @Before("@annotation(com.example.jdbc.config.Tenant)") public void setTenant(JoinPoint joinPoint) { // 获取租户ID,可以从参数或上下文中获取 String tenantId = "id"; // 这里替换为实际获取租户ID的逻辑 TenantContext.setTenant(tenantId); } @After("@annotation(com.example.jdbc.config.Tenant)") public void clearTenant(JoinPoint joinPoint) { TenantContext.clear(); } }

Mybatis-plus配置


import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
            @Override
            public Expression getTenantId() {
                String tenantId = TenantContext.getTenant();
                if (tenantId != null) {
                    Expression expression= new StringValue(tenantId);
                    return expression;
                }
                return null; // 如果没有租户信息,不添加租户条件
            }

            @Override
            public String getTenantIdColumn() {
                return "tenant_id"; // 替换为实际的租户字段名
            }

            @Override
            public boolean ignoreTable(String tableName) {
                String tenantId = TenantContext.getTenant();
                if (tenantId == null) {
                    return true;
                }
                // 配置不需要租户隔离的表,例如系统表
            }
        }));
        return interceptor;
    }
}

注意:net.sf.jsqlparser.expression.Expression getTenantId() 获取租户 ID 值表达式,只支持单个 ID 值

posted @ 2024-05-17 13:52  轻寒  阅读(26)  评论(0编辑  收藏  举报