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

一、概述

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

二、核心类职责

类 路径 职责
ShardInteConfig biz/config/ShardInteConfig.java 配置类,注册拦截器并绑定 Handler
TableShardHandler biz/handle/TableShardHandler.java 拦截器回调,执行表名拼接
DataShardStrategyHelper biz/handle/DataShardStrategyHelper.java ThreadLocal 工具类,存取/清除后缀
ShardTableConfig biz/config/properties/ShardTableConfig.java 配置属性,定义默认后缀值

三、调用链路

scss 复制代码
业务方法 → setShardType(type) → setShardingTableSuffix(suffix)
                                    ↓ (ThreadLocal 存储)
                         MyBatis 执行 SQL
                                    ↓
              DynamicTableNameInnerInterceptor 拦截
                                    ↓
              TableShardHandler.dynamicTableName(sql, tableName)
                                    ↓
              tableName + "_" + suffix  →  实际物理表名
                                    ↓
                         业务方法 finally → clearShardType()

四、各层详细逻辑

4.1 配置层

java 复制代码
@Bean("shardingMybatisPlusInterceptor")
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    DynamicTableNameInnerInterceptor interceptor = new DynamicTableNameInnerInterceptor();
    interceptor.setTableNameHandler(new TableShardHandler());
    interceptor.addInnerInterceptor(interceptor);
    return interceptor;
}

4.2 拦截层

java 复制代码
@Override
public String dynamicTableName(String sql, String tableName) {
    return tableShard(tableName);
}

public String tableShard(String tableName) {
    String suffix = DataShardStrategyHelper.getShardingTableSuffix();
    if (ObjectUtil.isNotEmpty(suffix)) {
        return tableName + "_" + suffix;
    }
    return tableName;
}

4.3 上下文传递层

java 复制代码
private static ThreadLocal<String> shardingTableSuffix = new ThreadLocal<>();

public static void setShardingTableSuffix(String suffix)   // 设置
public static String getShardingTableSuffix()               // 获取
public static void clearShardingTableSuffix()               // 清除

五、业务使用模式

java 复制代码
public List<XxxResponse> someMethod(String type) {
    try {
        if (StringUtils.isBlank(type)) {
            type = shardTableConfig.getWechatTableType();
        }
        setShardType(type);
        // 执行数据库操作...
    } finally {
        clearShardType();
    }
}

六、分表效果示例

type 参数 实际查询表
"wechat" t_product_wechat
"web" t_product_web
null t_product_wechat(默认)

七、设计特点

  1. 线程安全:基于 ThreadLocal,请求线程独立
  2. 侵入小:业务方法前后 set/clear,Mapper 层无感知
  3. 灵活路由:请求参数动态决定分表
  4. 防御性编程:finally 确保 ThreadLocal 清除
相关推荐
独泪了无痕11 小时前
Spring Data Redis 快速上手
spring boot·redis·后端
m0_6399069415 小时前
Linux 操作系统入门:目录结构、服务排查常用命令、Shell 脚本基础
linux·运维·后端
holly就是我16 小时前
AI 编程助手为什么跑偏?用开源 ccglass 看清 Prompt、工具调用和 Token 消耗
人工智能·后端
鸿蒙开发16 小时前
共享 Schema 与 SchemaFactory
前端·后端·harmonyos
用户7884773163416 小时前
小程序后端三选一:云开发、.NET WebAPI、Node,我按客户现状分了三种答案
后端
aiopencode16 小时前
局域网设备抓包怎么做?用 TraceEagle 抓电视、游戏机和 IoT 流量
后端·ios
智驭未来掌门人16 小时前
CLion 开发 Qt 项目的优势
后端
EnCi Zheng16 小时前
后端怎么把AI接口稳定安全低成本接进业务:超时重试、密钥隔离与成本熔断清单
人工智能·后端·安全·架构·api
Bazingga16 小时前
从一家酒店讲懂Docker
后端
南归北隐16 小时前
Spring AI Alibaba Graph框架实现MCP数据库查询实战
java·后端·spring ai·mcp·spring ai mcp