MyBatis-Plus Dynamic Table Starter:分表不再痛苦,一行注解搞定

这是我开源的 MyBatis-Plus 动态表名 Starter,聚焦"简单、稳定、可扩展"的分表实践。本文通过动机、特性、安装、快速上手、进阶用法与常见问题,带你在 10 分钟内掌握并落地动态表名分表。

为什么需要动态表名

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

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

亮点特性

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

安装

Maven:

xml 复制代码
<dependency>
    <groupId>com.lizhuolun</groupId>
    <artifactId>mybatis-plus-dynamic-table-starter</artifactId>
    <version>1.0.0</version>
</dependency>

Gradle:

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 启用并编写策略。

yaml 复制代码
# 动态表名配置
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
  1. 代码即用:注解或工具类两种方式任选。

注解方式(推荐):

java 复制代码
@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;
    }
}

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

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

进阶用法

  • 多表同时路由:一次性指定多个逻辑表到实际分表,批量操作一致。
java 复制代码
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 即可接入你自己的路由规则。
java 复制代码
@Component
public class CustomTableRouterStrategy implements TableRouterStrategy {
  @Override public boolean match(String logicTableName) { return "t_custom".equals(logicTableName); }
  @Override public String getActualTableName(String logic, Object ctx) { return logic + "_" + suffix(ctx); }
  @Override public String getStrategyName() { return "CustomTableRouterStrategy"; }
  @Override public int getPriority() { return 100; }
}

调试与性能

  • 开启日志定位:
yaml 复制代码
dynamic-table:
  enable-sql-log: true
logging:
  level:
    com.lizhuolun.mybatis.dynamic: DEBUG
  • 推荐连接池:
yaml 复制代码
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)

结语

希望这个 Starter 能让你的分表实现"简单好用、可长期维护"。如果帮助到了你,欢迎在 GitHub 点个 ⭐️ Star!

相关推荐
Mos_x2 小时前
集成RabbitMQ+MQ常用操作
java·后端
该用户已不存在2 小时前
AI编程工具大盘点,哪个最适合你
前端·人工智能·后端
间彧2 小时前
云服务相关术语解读
后端
Ray663 小时前
JDK21 升级
后端
间彧3 小时前
SkyWalking详解与应用实战
后端
Python私教3 小时前
使用FastAPI+FastCRUD自动生成API接口
后端
Python私教3 小时前
使用 FastAPI+FastCRUD 快速开发博客后端 API 接口
后端
程序员阿达3 小时前
开题报告之基于SpringBoot框架的图书借阅系统的设计与实现
java·spring boot·后端
Eoch773 小时前
吃透 Java 核心技术:JVM 调优、并发安全、微服务开发,解决 90% 企业级场景问题
java·后端