租户隔离方案

293 阅读1分钟

步骤

  1. 用户与业务表增加身份标志字段 例:eid 1: 正式 2: 测试

  2. 网关接收到请求后,根据token获取用户信息,转发请求时将eid放到 Header中,实现了GatewayFilter

  3. 底层服务通过HandlerInterceptor进行拦截,获取eid放到ThreadLocal中,方便之后每次拼装sql时获取,方法执行完删除

  4. 封装TenantLineInnerInterceptor 拦截器(实现InnerInterceptor),放到MybatisPlus的拦截器MybatisPlusInterceptor中(实现了Mybatis的Interceptor接口)

  5. 实现TenantLineHandler接口,实现3个抽象方法。

    1. 设置是否需要过滤的表:ThreadLoal中eid为空或不在扫描表之内。特定表来源:@PostConstrust中扫描po路径下有@TableName注解的类且po中有eid字段
    2. 设置租户列名
    3. 设置租户值

具体执行流程


MybatisPlusInterceptor // 实现mysql的Interceptor#intercept

-> TenantLineInnerInterceptor#beforeQuery  // 执行mp的拦截器(也是多个)

-> TenantLineInnerInterceptor#parserSingle -> CCJSqlParserUtil#parse // 通过sql解析器,将sql进行拆分,查询字段、主表、关联表、where条件等

-> JsqlParserSupport#processParser // 判断是 增、删、改、查的哪一种,调不同的方法处理

-> TenantLineInnerInterceptor#processSelect // 判断是单表、多表

-> tenantLineHandler#ignoreTable,// 是否需要忽略当前表 

-> tenantLineHandler#getTenantIdColumn、 tenantLineHandler#getTenantId // 拼装参数,设置where条件。如:拼装 and eid = 1

-> 设置sql