news 2026/8/21 19:54:47

MyBatis-Plus 动态分表实战:基于 DynamicTableNameInnerInterceptor 的多端数据隔离方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MyBatis-Plus 动态分表实战:基于 DynamicTableNameInnerInterceptor 的多端数据隔离方案

MyBatis-Plus 动态分表实战:基于 DynamicTableNameInnerInterceptor 的多端数据隔离方案

一、概述

本文基于MyBatis-PlusDynamicTableNameInnerInterceptor实现动态分表,核心思路是:在 SQL 执行前,通过 ThreadLocal 传递表名后缀,拦截器自动将逻辑表名替换为物理表名,从而实现多端数据隔离(如端 At_product_a、端 Bt_product_b)。

二、核心类职责

职责
ShardInterceptorConfig配置类,注册拦截器并绑定 Handler
TableNameShardHandler拦截器回调,执行表名拼接
ShardContextHelperThreadLocal 工具类,存取/清除后缀
ShardTableProperties配置属性,定义默认后缀值

以上类名均为示意,实际项目中按自身命名规范调整。

三、调用链路

业务方法 → setShardType(type) → ShardContextHelper.setShardSuffix(suffix) ↓ (ThreadLocal 存储) MyBatis 执行 SQL ↓ DynamicTableNameInnerInterceptor 拦截 ↓ TableNameShardHandler.dynamicTableName(sql, tableName) ↓ ShardContextHelper.getShardSuffix() ↓ tableName + "_" + suffix → 实际物理表名 ↓ 业务方法 finally → clearShardType()

四、各层详细逻辑

4.1 配置层 —ShardInterceptorConfig

@Bean("shardingMybatisPlusInterceptor")publicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptor=newMybatisPlusInterceptor();DynamicTableNameInnerInterceptordynamicTableNameInnerInterceptor=newDynamicTableNameInnerInterceptor();dynamicTableNameInnerInterceptor.setTableNameHandler(newTableNameShardHandler());interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);returninterceptor;}
  • 创建DynamicTableNameInnerInterceptor,设置全局唯一的TableNameShardHandler
  • 该拦截器会拦截所有 SQL,对每张表都调用 Handler

4.2 拦截层 —TableNameShardHandler

@OverridepublicStringdynamicTableName(Stringsql,StringtableName){returntableShard(tableName);}publicStringtableShard(StringtableName){Stringsuffix=ShardContextHelper.getShardSuffix();if(ObjectUtil.isNotEmpty(suffix)){returntableName+"_"+suffix;}returntableName;}
  • 从 ThreadLocal 读取后缀,非空则拼接原表名_后缀
  • 后缀为空时原样返回,即不设置后缀的查询走原表

4.3 上下文传递层 —ShardContextHelper

privatestaticThreadLocal<String>shardSuffix=newThreadLocal<>();publicstaticvoidsetShardSuffix(Stringsuffix)// 设置publicstaticStringgetShardSuffix()// 获取publicstaticvoidclearShardSuffix()// 清除
  • 使用ThreadLocal保证线程隔离,不同请求可路由到不同分表
  • 提供 set/get/clear 三段式操作

4.4 配置属性层 —ShardTableProperties

privateStringtableTypes="a,b";// 支持的分表类型privateStringdefaultType="a";// 默认后缀
  • defaultType:默认后缀为"a",即未指定 type 时默认查端 A 分表
  • tableTypes:声明了支持的分表类型列表

五、业务使用模式

所有业务类遵循统一的try-finally 模式

publicList<XxxResponse>someMethod(Stringtype){try{// 1. 确定后缀:未传则用默认值if(StringUtils.isBlank(type)){type=shardTableProperties.getDefaultType();}// 2. 设置 ThreadLocalsetShardType(type);// 3. 执行数据库操作(此时 SQL 中的表名已被拦截器替换)...}finally{// 4. 清除 ThreadLocal,防止线程复用导致污染clearShardType();}}

适用场景示例

场景分表用途
运营内容管理不同端的内容隔离(tabs/files/guides)
行业列表按端隔离行业数据
产品列表按端隔离产品数据
资源文件按端隔离文件资源
收藏功能按端隔离用户收藏

六、分表效果示例

假设逻辑表名为t_product

type 参数ThreadLocal 后缀实际查询表
"a"at_product_a
"b"bt_product_b
null/ 空a(默认)t_product_a

七、设计特点

  1. 线程安全:基于 ThreadLocal,每个请求线程独立,互不干扰
  2. 对业务代码侵入小:只需在业务方法前后 set/clear,Mapper 层无感知
  3. 灵活路由:通过请求参数动态决定查哪张分表,支持多端数据隔离
  4. 防御性编程:finally 块确保 ThreadLocal 清除,避免线程池复用污染

八、潜在问题

8.1 全局拦截无差别替换

DynamicTableNameInnerInterceptor会对所有表执行 Handler,包括不需要分表的表。当 ThreadLocal 有值时,所有表名都会被拼接后缀,若某张表不存在对应的分表则会报错。当前依赖"不设后缀则不替换"来规避,但一旦忘记 clear 或在嵌套调用中设置,可能误伤其他表。

8.2 异步线程丢失上下文

如果业务方法中使用了CompletableFuture异步并发查询,子线程无法继承父线程的 ThreadLocal 值。若主线程未设置分表后缀就提交了异步任务,子线程中的查询可能走错表或走原表。

8.3 set/clear 重复散落

每个业务类都重复编写了setShardType()/clearShardType()方法,且 try-finally 模板代码大量重复,可抽取为模板方法或 AOP 切面统一管理。

8.4 命名规范

方法名中 “Shard” 拼写需统一(Shard = 分片),避免 “Shading”(阴影)等拼写错误混入。

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

三步保存视频号视频:免费开源资源嗅探下载工具的完整上手指南

三步保存视频号视频&#xff1a;免费开源资源嗅探下载工具的完整上手指南 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 深夜…

作者头像 李华
网站建设 2026/8/21 19:52:32

LenovoLegionToolkit 电源模式不同步?30秒自检 + 完整修复流程

LenovoLegionToolkit 电源模式不同步&#xff1f;30秒自检 完整修复流程 【免费下载链接】LenovoLegionToolkit Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops. 项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolkit 切…

作者头像 李华
网站建设 2026/8/21 19:52:16

C++ Vector核心解析与面试高频考点实战

1. 项目概述 "攻克算法面试&#xff1a;C Vector 核心问题精讲"这个主题直指程序员在技术面试中最常遇到的痛点之一——对C标准模板库(STL)中vector容器的深入理解和应用能力。作为C中最基础也最常用的容器&#xff0c;vector在算法面试中的出现频率高达70%以上&…

作者头像 李华
网站建设 2026/8/21 19:51:53

威海教师评职称需要满足哪些条件?2026年最新政策解读

威海教师评职称需要满足学历、资历、教学业绩、科研能力、继续教育等多方面条件&#xff0c;具体标准根据申报级别有所不同。根据威海市人力资源和社会保障局2025年7月30日发布的《威海市职称评审申报指南&#xff08;2025年度&#xff09;》&#xff0c;教师职称评审已形成规范…

作者头像 李华
网站建设 2026/8/21 19:50:46

2026四大AI论文写作软件深度横评|从降重到润色,各有所长别盲选

近几年AI写论文早已普及&#xff0c;但工具乱用直接踩雷。 很多同学分不清通用AI和学术AI的区别&#xff0c;不管是课程作业还是毕业论文&#xff0c;随便套用工具改写、润色、降重。最终出现AI检测超标、重复率居高不下、格式不符合学校规范、文献综述逻辑混乱等问题&#xff…

作者头像 李华
网站建设 2026/8/21 19:50:17

网络资源如何3步抓取?res-downloader 完整实战指南

网络资源如何3步抓取&#xff1f;res-downloader 完整实战指南 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 你有没有过这种…

作者头像 李华