跳到正文
堆栈茶社
返回

多租户的实现

更新于:
—次阅读
编辑此页

多租户概述

多租户(Multi Tenancy/Tenant)是一种软件架构,其定义是:在一台服务器上运行单个应用实例,它为多个租户提供服务。

数据隔离方案

  1. 独立数据库

    即一个租户一个数据库。

  2. 共享数据库,独立Schema

    即多个或所有租户共享Database,但是每个租户一个Schema(也可叫做一个user)。

  3. 共享数据库,共享Schema,共享数据表

    即租户共享同一个Database、同一个Schema,但在表中增加租户标识的数据字段。

实现方式

在MySQL没用schema和database的区分,所以上述1、2两种方案大体一致。当前选择最低成本的共享数据库,共享Schema,共享数据表方案。后续讨论全部针对于方案3展开。

简单来说,意味着每条数据都需要区分出属于哪个租户。为了减少后期开发成本,需要为用户表以及用户相关的表全都增加租户标识的字段(如tenantId)。

此时涉及与租户相关的SQL都需要拼接tenantId = ?,若手动拼接,改造过程过于繁琐。此时我们想到的方案是根据当前用户所属的租户动态的拼接SQL,恰巧MyBatis-Plus为我们提供了这样功能的插件,仅需要简单的配置即可。

MyBatis-Plus 的多租户 SQL 解析器配置

参考官方文档及demo https://mybatis.plus/guide/tenant.html

此处贴一下核心配置

@MapperScan("com.liuqitech.demo.dao")
@Configuration
public class MyBatisConfig {

  /**
   * 多租户的标识字段
   */
  private static final String TENANT_ID_COLUMN = "TENANT_ID";

  /**
   * 忽略多租户的表名
   */
  private static final List<String> IGNORE_TENANT_TABLES = Lists
      .newArrayList("table1", "table2", "table3", "table4");

  @Bean
  public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
    TenantSqlParser tenantSqlParser = new TenantSqlParser();
    tenantSqlParser.setTenantHandler(new TenantHandler() {
      @Override
      public Expression getTenantId(boolean where) {
      // TODO 此处的tenantId需要自己获取当前用户所属的租户
        String tenantId = "liuqitech";
        return new StringValue(tenantId);
      }

      @Override
      public String getTenantIdColumn() {
        return TENANT_ID_COLUMN;
      }

      @Override
      public boolean doTableFilter(String tableName) {
        return IGNORE_TENANT_TABLES.stream().allMatch(e -> e.equalsIgnoreCase(tableName));
      }
    });
    paginationInterceptor.setSqlParserList(Lists.newArrayList(tenantSqlParser));
    return paginationInterceptor;
  }

}

编辑此页
分享这篇文章:

上一篇
JVM笔记 - 运行时内存区域
下一篇
frp 内网穿透