Mybatis-plus多租户插件

目录

    • Mybatis-plus多租户插件
    • 实现原理
    • 使用

Mybatis-plus多租户插件

Mybatis-plus多租户插件是一种用于实现多租户功能的插件,它基于Mybatis框架,通过拦截器机制实现对多租户的支持。该插件的核心组件包括TenantHandler和TenantInterceptor,其中TenantHandler用于处理租户相关的逻辑,如获取租户ID、设置租户信息等;而TenantInterceptor则用于拦截需要处理多租户的SQL语句,并在SQL中添加租户条件。

官方说明:

  1. 多租户 != 权限过滤,不要乱用,租户之间是完全隔离的!!!
  2. 启用多租户后所有执行的method的sql都会进行处理.
  3. 自写的sql请按规范书写(sql涉及到多个表的每个表都要给别名,特别是 inner join 的要写标准的 inner join

实现原理

Mybatis-plus多租户插件的实现原理主要基于Mybatis的拦截器(Interceptor)机制,通过拦截器在需要执行的sql后面自动添加租户的查询条件,实现多租户功能。具体来说,Mybatis-plus提供了TenantLineInnerInterceptor租户处理器来实现多租户功能。在启用多租户后,所有执行的method的sql都会被处理,即自写的sql需要按照规范书写(sql涉及到多个表的每个表都要给别名,特别是inner join的要写标准的inner join)。

简单来说,Mybatis-plus多租户插件通过自定义Mybatis拦截器,在执行sql时自动添加租户的查询条件,实现多租户功能。

和基于物理隔离(分表)实现多租户不同,基于逻辑隔离(租户标识列,tenant_id)实现多租户是在每一张表中添加一个租户标识列(tenant_id),通过该列来区分各个租户的数据。

TenantLineInnerInterceptor插件也是基于逻辑隔离(租户标识列,tenant_id)实现多租户的,只不过它给我们封装了部分逻辑,让我们不用再SQL中显示地指定tenant_id作为条件,它会自动为我们拼接。

使用

1、自定义TenantLineHandler

下面是TenantLineHandler 接口的定义,主要是用于获取租户ID和表是否需要需要租户隔离判断

/*** 租户处理器( TenantId 行级 )** @author hubin* @since 3.4.0*/
public interface TenantLineHandler {/*** 获取租户 ID 值表达式,只支持单个 ID 值* <p>** @return 租户 ID 值表达式*/Expression getTenantId();/*** 获取租户字段名* <p>* 默认字段名叫: tenant_id** @return 租户字段名*/default String getTenantIdColumn() {return "tenant_id";}/*** 根据表名判断是否忽略拼接多租户条件* <p>* 默认都要进行解析并拼接多租户条件** @param tableName 表名* @return 是否忽略, true:表示忽略,false:需要解析并拼接多租户条件*/default boolean ignoreTable(String tableName) {return false;}/*** 忽略插入租户字段逻辑** @param columns        插入字段* @param tenantIdColumn 租户 ID 字段* @return*/default boolean ignoreInsert(List<Column> columns, String tenantIdColumn) {return columns.stream().map(Column::getColumnName).anyMatch(i -> i.equalsIgnoreCase(tenantIdColumn));}
}

自定义的TenantLineHandler ,我们需要按照自己的实际情况来定义自己的租户字段和获取

@Slf4j
@Component
public class MyTenantLineHandler implements TenantLineHandler {/*** 租户字段名*/private static final String SYSTEM_TENANT_ID = "tenant_id";/*** 默认的租户ID*/public static final Long DEFAULT_TENANT_ID = 1L;/*** 需要过滤的表*/private static final List<String> IGNORE_TENANT_TABLES = new ArrayList<>();/*** 获取租户ID值* @return*/@Overridepublic Expression getTenantId() {//获取登录用户的租户IDLong loginUserTenantId = getLoginUserTenantId();if (loginUserTenantId == null){loginUserTenantId = DEFAULT_TENANT_ID;}return new LongValue(loginUserTenantId);}/*** 租户字段名,默认是tenant_id,如果想改成其他字段,在这里返回即可* @return*/@Overridepublic String getTenantIdColumn() {return SYSTEM_TENANT_ID;}/*** 有不需要进行租户隔离的表,在这里返回true* @param tableName* @return*/@Overridepublic boolean ignoreTable(String tableName) {return IGNORE_TENANT_TABLES.contains(tableName);}public Long getLoginUserTenantId(){//模拟获取登录用户的租户ID,实际项目可以从登录用户缓存信息中获取return 1L;}}

2、添加租户ID字段

我们的表和实体类都需要添加上租户ID字段

表字段

  `tenant_id` bigint(20) NOT NULL COMMENT '多租户下的租户ID',

实体字段

   @TableField("tenant_id")private Long tenantId;

3、注册mybatisplus的多租户实现到 MybatisPlusInterceptor

@Configuration
public class MybatisPlusConfig {/*** 添加MP插件*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 添加多租户插件interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new MyTenantLineHandler()));//如果配置多个插件,切记分页最后添加,如果有多数据源可以不配具体类型 否则都建议配上具体的DbTypePaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);//设置单页分页最大数量paginationInnerInterceptor.setMaxLimit(500L);interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;}}

完成上面配置之后,Mybatisplus就会帮我们在增删改查的所有操作都给拼接上携带租户条件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/624303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全国博物馆数据, shp+excel数据,数据来源可靠,基于国家文物局发布的《2021年度全国博物馆名录》

数据名称: 全国博物馆数据 数据格式: shpexcel 数据几何类型: 点 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据&#xff0c;数据名录来源于国家文物局发布的《2021年度全国博物馆名录》 数据字段&#xff1a; 序号字段名称字段说明1province省份名称2city城市名…

不管你打开什么App,命运都会让我们相聚在购物软件

「不管打开什么 App &#xff0c;命运都会让我们相聚在购物平台。」 「现在谁还亲自打开淘宝和京东&#xff1f;随便打开一个 App 摇一摇&#xff0c;速度更快。」 最近&#xff0c;差评君在很多社交媒体平台都刷到了这样的段子。 如果你没get到啥意思&#xff0c;咱也不卖关…

一个完整的流程表单流转

1.写在前面 一个完整的流程表单审批&#xff08;起表单-->各环节审批-->回退-->重新审批-->完成&#xff09;&#xff0c;前端由Vue2jsElement UI升级为Vue3tsElement Plus&#xff0c;后端流程框架使用Flowable&#xff0c;项目参考了ruoyi-vue-pro(https://gite…

Java学习(十八)--网络编程

介绍 需求 如何准确地定位网络上一台或多台主机&#xff1b; 定位主机上的特定的应用 找到主机后如何可靠高效地进行数据传输 目的 直接或间接地通过网络协议与其它计算机实现数据交换&#xff0c;进行通讯&#xff1b; 网络通信 网络&#xff1a;两台或多台设备通过一…

怎样利用MATLAB制作图中图(局部放大图片)

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

Quick taxi route assignment via real-time intersection state prediction

Quick taxi route assignment via real-time intersection state prediction with a spatial-temporal graph neural network(通过时空图神经网络实时交叉口状态预测快速分配出租车路线) PAPER LINK 简单说一下: 本文采用了一种新的方法,通过使用空间-时间图神经网络(ST…

Python 获取数组中等于给定值大小的值

Python 获取数组中等于给定值大小的值 引言正文基础方法方法1方法2------使用 np.where() 函数方法3------数组操作 示例1示例 2 引言 可能很多小伙伴看到这个标题会觉得很绕口&#xff0c;甚至可能会觉得这属于脱裤子放屁&#xff0c;多此一举&#xff0c;但是这里请大家耐心…

基于位的权限系统

基于位的权限系统是一种利用二进制位运算进行权限管理的技术。在这种系统中&#xff0c;不同的权限被编码为2的幂次方 (例如1、2、4、8等)&#xff0c;每个权限对应一个独立的二进制位&#xff08;可想而知运算速度是非常快的&#xff09;。通过将这些权限值组合在一起形成一个…

力扣198. 打家劫舍(java 动态规划)

Problem: 198. 打家劫舍 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 1.构建多阶段决策模型&#xff1a;n个房屋对应n个阶段&#xff0c;每一个阶段决定一个房间是偷还是不偷&#xff0c;两种决策&#xff1a;偷、不偷 2.定义状态&#xff1a;不能记录每个阶段决策…

笔记系统的部署架构

前天给笔记系统打了0.0.3的tag&#xff0c;一个简单的全栈功能闭环基本完成。既然是开源&#xff0c;因此&#xff0c;这里有必要分享一下部署结构&#xff0c;希望能够获得小伙伴们的反馈。 目前整个系统采用docker容器来部署。应用介绍 auth_app: 登录/注册的前端应用 web_ap…

手动数据分页

public static PageInfo<Long> cutPage(SegmentVo vo, List<Long> segmentIds) {PageInfo<Long> result new PageInfo<>();// 总条数int total segmentIds.size();int currentPage vo.getPageNo();int pageSize vo.getPageSize();List<Long>…

西贝柳斯音乐记谱软件Avid Sibelius Ultimate 2023中文激活版

Avid Sibelius(西贝柳斯终极解锁版) 是一款记谱软件&#xff0c;从有抱负的作曲家和词曲作者到教师和学生&#xff0c;任何人都可以快速轻松地开始创作和分享音乐。对于那些还不熟悉使用符号软件的人来说&#xff0c;直观的界面将引导您完成整个过程。磁性布局可防止对象相互碰…

GBASE南大通用GBase Command Builder 构造函数

初始化GBASE南大通用CommandBuilder 类的一个对象。  重载列表 1) 初始化 GBaseCommandBuilder 类的一个对象。 GBaseCommandBuilder() 2) 使用 GBaseDataAdapter 对象初始化 GBaseCommandBuilder 类的一个 对象。 GBaseCommandBuilder(GBaseDataAdapter) GBaseCommand…

跨国企业如何高效又安全的传输视频大文件?

在视频传输需求日益增长的今天&#xff0c;如何高效、安全地传输视频大文件成为跨国企业面临的重要问题。传统的文件传输方式存在诸多弊端&#xff0c;无法满足跨国企业对于传输效率、文件安全以及合规性的需求。那么跨国企业如何在市场是找到一种文件传输工具能在安全性、稳定…

构建基于RHEL9系列(CentOS9,AlmaLinux9,RockyLinux9等)的MySQL8.0.32的RPM包

本文适用&#xff1a;rhel9系列&#xff0c;或同类系统(CentOS9,AlmaLinux9,RockyLinux9等) 文档形成时期&#xff1a;2023年 因系统版本不同&#xff0c;构建部署应略有差异&#xff0c;但本文未做细分&#xff0c;对稍有经验者应不存在明显障碍。 因软件世界之复杂和个人能力…

Elastic Search的RestFul API入门:DSL查询

在我们之前的基础篇中,我们已经初步了解了DSL的架构与基础结构。现在,我们将进一步学习DSL的查询语句,这些查询语句对于我们的工作和学习而言至关重要。 DSL(Domain Specific Language)是一种专门用于特定领域的编程语言。在Elasticsearch(ES)中,DSL被广泛用于构建灵活…

debug之pycharm调试:出现Collecting data......

pycharm调试时&#xff0c;出现Collecting data… 一直在这个界面很久&#xff0c;这是新版本的Pycharm的bug&#xff0c;通常在多线程的情况下发生。 解决方法&#xff1a; File->Setting->Build,Execution,Deployment->Python Debugger。把Gevent compatible勾选…

Postgresql 12.2 + PostGIS 3.0.1 安装部署

参考文档&#xff1a; 按照该文档安装即可&#xff0c;如果遇到报错&#xff0c;可以参考下文&#xff1a; https://blog.csdn.net/weixin_41166785/article/details/127674169 所需的安装包 在资源里面&#xff08;我看下怎么可以不用积分下载&#xff09; 1、no acceptable…

代码随想录算法训练营第六天 |242.有效的字母异位词,349.两个数组的交集,202.快乐数,1.两数只和

哈希表理论基础 1、哈希表定义&#xff1a; 哈希表是根据关键码的值而直接进行访问的数据结构。 这么这官方的解释可能有点懵&#xff0c;其实直白来讲其实数组就是一张哈希表。 哈希表中关键码就是数组的索引下标&#xff0c;然后通过下标直接访问数组中的元素&#xff0c…

花几分钟整点jmeter花活,轻松超越90%软件测试

jmeter 可以做性能测试&#xff0c;这个很多人都知道&#xff0c;那你知道&#xff0c;jmeter 可以在启动运行时&#xff0c;指定线程数和运行时间&#xff0c;自定义性能场景吗&#xff1f; jmeter 性能测试&#xff0c;动态设定性能场景 平时&#xff0c;我们使用 jmeter 进…