searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

基于Mybatis-Plus多租户方案简介

2023-05-29 06:22:52
24
0

背景介绍

多租户业务介绍

一个多租户系统的例子:

  1. 每家企业在系统里面都是一个租户。
  2. 每家企业在系统里面都有各自配置的组织架构、用户组与角色等。
  3. 一个用户可以属于多个不同的企业(租户)。

常见数据库方案介绍

在多租户架构中,常见数据库方案有三种:

  1. 独立数据库。
  2. 共享数据库,独立schema。
  3. 共享数据库,共享 schema,共享数据表。

方案1、2,修改或变更表结构时,需要去多个数据库或schema进行修改。对比方案1与方案2,方案3允许每个数据库支持的租户数量更多,维护和购置成本较低。

插件使用方式

配置插件

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
     
    //增加多租户插件
    interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantHandler() {
        @Override
        public Expression getTenantId() {
            return new LongValue(获取当前租户的逻辑);
        }
 
        @Override
        public boolean ignoreTable(String tableName) {
            return ignoreTableList.contains(tableName);
        }
    }));
    …………
    return interceptor;
}

某些表不进行租户过滤的配置

@Override
public boolean ignoreTable(String tableName) {
      return ignoreTableList.contains(tableName);
}

某些SQL语句不进行租户过滤的配置

在Mapper文件中,增加 @InterceptorIgnore(tenantLine = "1") 注解

@InterceptorIgnore(tenantLine = "1")
@Select("……………………")
Long hello(String username);

插件注意事项

语法问题

Mybatis-Plus使用jsqlparser来对语法进行解析与拼接租户id。jsqlparser基于SQL规范进行解析,一些特别的语法会异常。

例如CAST函数会出错,可更换为CONVERT函数。

表名问题

对于不需要多租户插件的库表,可以过滤掉这部分表名,但需要注意表名大小写、与` `符号的问题。

interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
    …………
    @Override
    public boolean ignoreTable(String tableName) {
        return ignoreTableList.contains(tableName);
    }
}));

解决方案: 配置文件中,统一用小写库表名。基础框架增加逻辑处理,并增加配置是否忽略大小写。

租户列多次插入问题(3.4.1版本已解决)

如果业务SQL本身已插入租户ID,多租户插件在启用多租户处理器的时候就会自动插入租户ID,你自己插入了租户ID,多租户处理器也给你插入了租户ID。

0条评论
0 / 1000
1****n
4文章数
0粉丝数
1****n
4 文章 | 0 粉丝
原创

基于Mybatis-Plus多租户方案简介

2023-05-29 06:22:52
24
0

背景介绍

多租户业务介绍

一个多租户系统的例子:

  1. 每家企业在系统里面都是一个租户。
  2. 每家企业在系统里面都有各自配置的组织架构、用户组与角色等。
  3. 一个用户可以属于多个不同的企业(租户)。

常见数据库方案介绍

在多租户架构中,常见数据库方案有三种:

  1. 独立数据库。
  2. 共享数据库,独立schema。
  3. 共享数据库,共享 schema,共享数据表。

方案1、2,修改或变更表结构时,需要去多个数据库或schema进行修改。对比方案1与方案2,方案3允许每个数据库支持的租户数量更多,维护和购置成本较低。

插件使用方式

配置插件

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
     
    //增加多租户插件
    interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantHandler() {
        @Override
        public Expression getTenantId() {
            return new LongValue(获取当前租户的逻辑);
        }
 
        @Override
        public boolean ignoreTable(String tableName) {
            return ignoreTableList.contains(tableName);
        }
    }));
    …………
    return interceptor;
}

某些表不进行租户过滤的配置

@Override
public boolean ignoreTable(String tableName) {
      return ignoreTableList.contains(tableName);
}

某些SQL语句不进行租户过滤的配置

在Mapper文件中,增加 @InterceptorIgnore(tenantLine = "1") 注解

@InterceptorIgnore(tenantLine = "1")
@Select("……………………")
Long hello(String username);

插件注意事项

语法问题

Mybatis-Plus使用jsqlparser来对语法进行解析与拼接租户id。jsqlparser基于SQL规范进行解析,一些特别的语法会异常。

例如CAST函数会出错,可更换为CONVERT函数。

表名问题

对于不需要多租户插件的库表,可以过滤掉这部分表名,但需要注意表名大小写、与` `符号的问题。

interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
    …………
    @Override
    public boolean ignoreTable(String tableName) {
        return ignoreTableList.contains(tableName);
    }
}));

解决方案: 配置文件中,统一用小写库表名。基础框架增加逻辑处理,并增加配置是否忽略大小写。

租户列多次插入问题(3.4.1版本已解决)

如果业务SQL本身已插入租户ID,多租户插件在启用多租户处理器的时候就会自动插入租户ID,你自己插入了租户ID,多租户处理器也给你插入了租户ID。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0