⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/7569536278255616036 「递归不能太深」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

这是我开源的 MyBatis-Plus 动态表名 Starter,聚焦“简单、稳定、可扩展”的分表实践。

本文通过动机、特性、安装、快速上手、进阶用法与常见问题,带你在 10 分钟内掌握并落地动态表名分表。

项目地址(Starter):

演示项目(Demo):

为什么需要动态表名

随着数据规模增长,按时间或按用户分片的“分表”成为常态。传统落地往往涉及:SQL 拼接、拦截器改造、策略维护与回归测试,成本高且容易出错。这个 Starter 以“注解 + 配置”的方式,将分表复杂度收敛到最小,实现:

  • 开箱即用,零侵入;
  • 注解驱动,写业务像写普通 CRUD;
  • 策略模式,扩展自定义分表逻辑更顺畅;
  • 完整日志与故障定位;

亮点特性

  • 开箱即用: 自动装配,默认启用;
  • 日期分表: 按年/按月/按日一键切换;
  • 哈希分表: 按哈希值均匀分片;
  • 注解驱动:@DateSharding、@HashSharding 即可;
  • 工具类支持:DynamicTableUtils 包裹任意代码块;
  • 灵活优先级: 多策略并存,优先级可控;
  • 完整日志: 定位策略匹配与表名替换过程;

安装

Maven:

<dependency>
<groupId>com.lizhuolun</groupId>
<artifactId>mybatis-plus-dynamic-table-starter</artifactId>
<version>1.0.0</version>
</dependency>

Gradle:

implementation 'com.lizhuolun:mybatis-plus-dynamic-table-starter:1.0.0'

运行环境:Java 21+,Spring Boot 3.5.6+,MyBatis-Plus 3.5.14+

快速上手(3步)

1.添加依赖: 确保引入 Spring Web 与 MyBatis-Plus Starter。

2.配置分表策略: 在 application.yml 启用并编写策略。

# 动态表名配置
dynamic-table:
enabled:true
enable-sql-log:true

# 日期分表:订单与日志按月/按日分表
date-sharding:
-tables:[t_order,t_log]
date-pattern:"yyyyMM"
priority:1
-tables:[t_access_log]
date-pattern:"yyyyMMdd"
priority:2

# 哈希分表:用户相关表分8张
hash-sharding:
-tables:[t_user,t_user_profile]
table-count:8
priority:10

3.代码即用: 注解或工具类两种方式任选。

注解方式(推荐):

@Service
public class OrderService {
@Autowired private OrderMapper orderMapper;

// 自动根据日期分表(如 t_order_202501)
@DateSharding(value = "t_order", dateParam = "date")
public Order create(Order order, LocalDate date) {
orderMapper.insert(order);
return order;
}
}

工具类方式(灵活包裹任意代码块):

public List<Order> queryByDate(LocalDate date) {
return DynamicTableUtils.executeWithDate("t_order", date, () -> {
return orderMapper.selectList(null);
});
}

进阶用法

多表同时路由: 一次性指定多个逻辑表到实际分表,批量操作一致。

Map<String, String> tableMap = Map.of(
"t_order", "t_order_202501",
"t_log", "t_log_202501"
);
DynamicTableUtils.executeWithTables(tableMap, () -> {
orderMapper.insert(order);
logMapper.insert(log);
});

自定义策略: 实现 TableRouterStrategy 即可接入你自己的路由规则。

@Component
publicclass CustomTableRouterStrategy implements TableRouterStrategy {
@Overridepublic boolean match(String logicTableName) { return"t_custom".equals(logicTableName); }
@Overridepublic String getActualTableName(String logic, Object ctx) { return logic + "_" + suffix(ctx); }
@Overridepublic String getStrategyName() { return"CustomTableRouterStrategy"; }
@Overridepublic int getPriority() { return100; }
}

调试与性能

开启日志定位:

dynamic-table:
enable-sql-log: true
logging:
level:
com.lizhuolun.mybatis.dynamic: DEBUG

推荐连接池:

spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000

常见问题(FAQ)

  • 表名未替换:检查是否在 tables 列表中、策略是否匹配、日志是否打印。
  • 策略不生效:确认注解参数(如 dateParam / hashKey)与方法入参对应,AOP 正常工作。
  • SQL 异常:核验实际分表是否存在、表结构是否一致;查看日志中的替换结果。

适用场景与对比

  • 业务归档:订单/日志随时间增长,按月/日归档查询更快。
  • 用户分片:按照用户维度分散热点写入与读压力。
  • 与手写拦截器对比:本项目更轻量、配置化、可扩展;注解即用,维护成本低。

Demo 与快速验证

  • 进入 mybatis-plus-dynamic-table-demo,根据 README 初始化数据库并启动 mvn spring-boot:run;
  • 使用 curl 或 Postman 调用示例接口,观察 SQL 替换与分表效果;

路线图(Roadmap)

  • 更多策略模板与表达式支持;
  • 更丰富的示例与最佳实践;
  • 生产问题排查指引与灰度方案;

生态与兼容

  • 运行:Java 21+ / Spring Boot 3.5.6+ / MyBatis-Plus 3.5.14+
  • 许可:Apache-2.0
  • 贡献:欢迎提交 Issue / PR(详见仓库 CONTRIBUTING)
文章目录
  1. 1. 为什么需要动态表名
  2. 2. 亮点特性
  3. 3. 安装
  4. 4. 快速上手(3步)
  5. 5. 进阶用法
  6. 6. 调试与性能
  7. 7. 常见问题(FAQ)
  8. 8. 适用场景与对比
  9. 9. Demo 与快速验证
  10. 10. 路线图(Roadmap)
  11. 11. 生态与兼容