讲师中心 微信公众号
AI工具推荐 视频效率加速

如何利用 MyBatis 插件拦截机制在执行 SQL 前自动化实现多租户数据权限隔离

大磊酱_4411

大磊酱_4411

发布时间:2026-05-02 19:32:06

|

911人浏览过

|

来源于php中文网

原创

必须拦截 StatementHandler,因为 Executor 拦截太晚、ParameterHandler 不处理 SQL 结构;StatementHandler.prepare() 是 SQL 最终定型节点,需在此前用 JSqlParser 解析 AST 并安全注入租户条件,同时严格管控 TenantContext 线程传递与表过滤逻辑。

如何利用 mybatis 插件拦截机制在执行 sql 前自动化实现多租户数据权限隔离

必须拦截 StatementHandler,否则 SQL 改写无效——Executor 拦截太晚,ParameterHandler 根本不碰 SQL 结构。

为什么不能拦 Executor?

常见错误是用 @Intercepts 注解指向 Executor.update 或 Executor.query,结果发现 WHERE 条件加不进去。因为此时 MappedStatement 已封装好完整 BoundSql,SQL 字符串早已生成完毕,再改 BoundSql.getSql() 属于“事后补救”,MyBatis 不会重新解析或校验语法,极大概率触发 MySQLSyntaxErrorException 或漏过滤。

  • Executor 负责执行,不参与 SQL 拼接与结构构建
  • StatementHandler.prepare() 才是 SQL 最终定型的节点:它调用 SqlSource.getBoundSql(),并准备 PreparedStatement
  • 所有安全的 SQL 改写(如插入 tenant_id = ?)必须发生在这个方法调用之前

怎么安全地改写 SQL 而不破坏语法?

不能直接字符串拼接 " AND tenant_id = '" + tenantId + "'"——原始 SQL 可能没有 WHERE、可能含 UNION、可能嵌套子查询,硬追加必然出错。

  • 正确路径是解析 SQL AST:用 JSqlParser 解析 SELECT/UPDATE/DELETE 语句,定位主查询的 PlainSelect.getWhere()
  • 若原无 WHERE,用 AndExpression 合并;若有,则用 BinaryExpression 追加条件
  • INSERT 场景无需改写 SQL,那是 MetaObjectHandler 的事(自动填充字段值),插件只管查/改/删的过滤逻辑
  • 务必在解析前判断表名:系统表如 sys_user、sys_dict 必须进 ignoreTables 列表,否则管理员登录时连用户表都查不到

TenantContext 的 tenant_id 从哪来、怎么传才可靠?

ThreadLocal 是唯一可控方式,但必须自己封装,不能依赖 RequestContextHolder。

  • JWT Filter 或网关层解析 token 后,立刻调用 TenantContext.setTenantId("t001") 存入静态 ThreadLocal
  • RequestContextHolder 依赖 Servlet 容器,在 @Async、定时任务、RabbitMQ 消费线程中会丢失上下文,导致 tenant_id 为空或错乱
  • 异步场景必须手动透传:比如用 TaskDecorator 包装线程池,或在 @RabbitListener 方法开头显式调用 TenantContext.setTenantId(...)
  • 千万别在拦截器里查数据库取 tenant_id:那等于每次请求多一次 DB 查询,违背“零侵入”设计初衷

用 MyBatis-Plus 的 TenantLineInnerInterceptor 真的省事吗?

是的,但它不是黑盒——你仍需理解底层约束,否则上线后踩坑更难排查。

  • 它内部也是拦 StatementHandler,并用类似 JSqlParser 的机制做 AST 改写
  • 必须实现 TenantLineHandler.getTenantId() 返回 Expression(不是字符串!),否则无法支持 IN 或 IS NULL 等复杂条件
  • doTableFilter(String tableName) 返回 true 表示跳过该表,这个逻辑一旦写错(比如漏了 sys_role),权限体系就崩了
  • 它不处理 INSERT SELECT、REPLACE INTO 等非常规语句,这些得靠自定义插件兜底

最易被忽略的点:租户上下文的生命周期必须和 SQL 执行严格对齐。一次 HTTP 请求可能跨多个线程(如 Dubbo 异步回调、CompletableFuture.thenApply),ThreadLocal 不会自动继承,不手动透传就等于没隔离。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

相关专题

更多
mybatis一级缓存和二级缓存
mybatis一级缓存和二级缓存

在MyBatis中,一级缓存和二级缓存是两种不同级别的缓存机制,它们都可以用来提高性能。本专题提供mybatis一级缓存和二级缓存相关文章,大家可以免费阅读。

583

2023.08.21

ibatis和mybatis有什么区别
ibatis和mybatis有什么区别

ibatis和mybatis的区别:1、基本信息不同;2、开发时间不同;3、功能与易用性;4、配置文件;5、入参类型与出参类型;6、返回结果集接受方式;7、语法差异;8、数据库方言支持;9、插件支持;10、社区活跃度;11、全球化支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2582

2024.02.23

mybatis如何配置数据库连接
mybatis如何配置数据库连接

mybatis配置数据库连接的方法:1、指定数据源;2、配置事务管理器;3、配置类型处理器和映射器;4、使用环境元素;5、配置别名。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

446

2024.02.23

mybatis工作原理及流程是什么
mybatis工作原理及流程是什么

mybatis工作原理及流程:1、配置文件;2、接口与映射;3、sql解析与生成;4、执行计划;5、结果处理;6、动态sql;7、缓存机制;8、插件;9、事务管理;10、日志与监控;11、扩展性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

292

2024.02.23

hibernate和mybatis有哪些区别
hibernate和mybatis有哪些区别

hibernate和mybatis的区别:1、实现方式;2、性能;3、对象管理的对比;4、缓存机制。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

302

2024.02.23

Java MyBatis框架
Java MyBatis框架

本专题专注于Java主流ORM框架MyBatis的应用,系统讲解SQL映射、动态SQL、结果映射、分页查询、缓存机制与多表关联等核心内容,并结合企业管理系统、电商平台和后台管理项目实战,帮助学员全面掌握高效的数据库持久层开发技能。

5849

2025.08.26

Playwright 测试失败怎么办
Playwright 测试失败怎么办

Playwright测试失败专题汇集超时、定位器匹配、浏览器提前关闭、依赖与插件配置、文件上传、SSL及Docker启动等故障文章,并介绍通过截图、报告和Trace定位错误。

0

2026.10.21

Playwright 页面操作指南
Playwright 页面操作指南

Playwright页面操作专题汇集元素定位、点击与输入、等待响应、多页面切换、Iframe、事件监听及文件处理的已审核文章,便于按操作场景查阅示例与常见问题。

0

2026.10.21

Playwright 入门教程
Playwright 入门教程

Playwright入门专题汇集测试框架安装、VS Code配置、录制脚本、编写首个用例、运行调试及查看报告的已审核文章,帮助初学者搭建端到端测试流程。

0

2026.10.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn