news 2026/4/23 9:16:03

如何添加“默认给Sql查询语句加上租户条件”的功能

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何添加“默认给Sql查询语句加上租户条件”的功能

从零实现“默认给 SQL 查询语句加上租户条件”的功能,本质上是利用MyBatis Plus的插件机制配合ThreadLocal上下文来实现的。

我们需要构建一条完整的“数据 -> 规则 -> 执行”的链路。以下是标准化的5 步实现指南


第一步:准备“背包” (定义上下文容器)

你需要一个地方在当前线程中存储“当前租户是谁”。

代码核心:利用ThreadLocal

publicclassTenantContextHolder{// 存放当前租户IDprivatestaticfinalThreadLocal<Long>TENANT_ID=newTransmittableThreadLocal<>();publicstaticvoidsetTenantId(LongtenantId){TENANT_ID.set(tenantId);}publicstaticLonggetTenantId(){returnTENANT_ID.get();}publicstaticvoidclear(){TENANT_ID.remove();}}

第二步:制定“规则” (实现 Handler 接口)

你需要告诉 MyBatis Plus 具体的过滤逻辑:租户ID是多少?列名叫什么?哪些表不需要加?

代码核心:实现TenantLineHandler接口。

@ComponentpublicclassMyTenantLineHandlerimplementsTenantLineHandler{// 1. 告诉 MP,当前租户ID是多少 (从背包里拿)@OverridepublicExpressiongetTenantId(){LongtenantId=TenantContextHolder.getTenantId();// 如果没拿到ID(比如没登录),返回 NullValue 可能会导致报错或查不到数据// 通常这里会做判空或者返回默认值returnnewLongValue(tenantId);}// 2. 告诉 MP,数据库里租户列的名字叫什么@OverridepublicStringgetTenantIdColumn(){return"tenant_id";}// 3. 告诉 MP,哪些表需要忽略 (白名单)@OverridepublicbooleanignoreTable(StringtableName){// A. 全局白名单:系统表(字典、菜单)不需要隔离if("sys_dict".equals(tableName)||"sys_menu".equals(tableName)){returntrue;}// B. 动态白名单:配合 @TenantIgnore 注解使用if(TenantContextHolder.isIgnore()){returntrue;}// 默认:必须加过滤条件returnfalse;}}

第三步:组装“引擎” (配置 MyBatis 拦截器)

有了规则(Handler),你需要把它交给执行者(Interceptor),并把执行者放入 MyBatis 的插件链中。

代码核心:配置MybatisPlusInterceptorBean。

@ConfigurationpublicclassMybatisConfig{@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(MyTenantLineHandlertenantLineHandler){MybatisPlusInterceptorinterceptor=newMybatisPlusInterceptor();// 核心动作:创建租户拦截器,并注入上面的规则 Handler// ⚠️注意:建议放在分页插件之前interceptor.addInnerInterceptor(newTenantLineInnerInterceptor(tenantLineHandler));// 添加分页插件interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));returninterceptor;}}

第四步:数据“注入” (配置 Web 过滤器)

引擎装好了,但还得有人把燃料(租户ID)塞进第一步的“背包”里。通常是在请求刚进来时处理。

代码核心:实现FilterHandlerInterceptor

@ComponentpublicclassTenantContextFilterimplementsFilter{@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain){try{// 1. 从请求头 Header 获取 tenant-idHttpServletRequestreq=(HttpServletRequest)request;StringtenantIdStr=req.getHeader("tenant-id");if(tenantIdStr!=null){// 2. 塞进 ThreadLocal 背包TenantContextHolder.setTenantId(Long.valueOf(tenantIdStr));}// 3. 放行,执行后续业务逻辑 (Service -> Mapper -> SQL拦截器)chain.doFilter(request,response);}finally{// 4. 【重要】请求结束,清空背包,防止线程污染TenantContextHolder.clear();}}}

🌟 总结:这一套下来发生了什么?

  1. 请求进来:Filter 从 Header 拿到tenant_id=1,存入TenantContextHolder
  2. 业务查询:你写了userMapper.selectList(null)
  3. 拦截改写TenantLineInnerInterceptor拦截 SQL,调用MyTenantLineHandler
  4. 读取规则:Handler 从TenantContextHolder拿到1
  5. SQL 变身:SQL 被自动拼接为SELECT * FROM user WHERE tenant_id = 1
  6. 请求结束:Filter 清空TenantContextHolder

这就是实现“全自动多租户隔离”的完整标准流程。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 13:30:02

2.2 黄金年代(1956-1974):推理证明、感知机与早期乐观主义

2.2 黄金年代&#xff08;1956-1974&#xff09;&#xff1a;推理证明、感知机与早期乐观主义 以1956年达特茅斯会议为起点&#xff0c;至1970年代中期&#xff0c;人工智能领域进入了其第一个繁荣阶段&#xff0c;常被称为“黄金年代”。这一时期&#xff0c;研究者在符号推理…

作者头像 李华
网站建设 2026/4/22 22:01:10

推广费,如何做账报税?

借&#xff1a;销售费用-推广费 应交税费-应交增值税(进项税额)贷&#xff1a;银行存款 一、增值税&#xff1b;可抵扣进项税额&#xff0c;不受15%限额影响&#xff1b; 二、所得税&#xff1b;季度预交所得税&#xff0c;不受15%限额影响&#xff1b; 三、所得税&…

作者头像 李华
网站建设 2026/4/23 13:28:58

基于EmotiVoice的有声内容创作全流程详解

基于EmotiVoice的有声内容创作全流程详解 在AI生成内容&#xff08;AIGC&#xff09;浪潮席卷各行各业的今天&#xff0c;语音合成早已不再是“机器人念稿”的代名词。从深夜陪伴型播客到沉浸式游戏NPC对话&#xff0c;用户期待的不再只是“能听清”&#xff0c;而是“听得进去…

作者头像 李华
网站建设 2026/4/23 10:43:41

EmotiVoice语音合成中的情感强度分级标准建立建议

EmotiVoice语音合成中的情感强度分级标准建立建议 在虚拟偶像与AI助手日益普及的今天&#xff0c;用户早已不再满足于“能说话”的机器声音。他们期待的是有温度、有情绪、能共情的语音交互体验。然而&#xff0c;当开发者试图让一个AI角色表达“开心”时&#xff0c;却常常陷入…

作者头像 李华
网站建设 2026/4/23 12:10:41

EmotiVoice支持的音频采样率与格式全解析

EmotiVoice支持的音频采样率与格式全解析 在语音合成技术飞速发展的今天&#xff0c;用户对“像人一样说话”的AI声音期待越来越高。从短视频配音到虚拟主播&#xff0c;从智能客服到无障碍阅读&#xff0c;情感丰富、音色自然的TTS&#xff08;Text-to-Speech&#xff09;系统…

作者头像 李华
网站建设 2026/4/23 10:45:04

EmotiVoice语音合成在语音导航系统中的情感提示设计

EmotiVoice语音合成在语音导航系统中的情感提示设计 在高速公路上连续驾驶两小时后&#xff0c;你是否曾对车载导航那句一成不变的“前方500米右转”感到麻木&#xff1f;又或者&#xff0c;在暴雨夜中变道时&#xff0c;一个毫无波澜的提醒根本无法唤起应有的警觉&#xff1f;…

作者头像 李华