前言
随着业务发展,数据库单表量将会持续增长,当增长到一定大小,是需要对应的处理以解决数据查询越来越慢的问题的。
一般的扩展方案分为两种,一种是垂直扩展,即增大单机的配置。 另一种则是水平扩展,是将任务分配到多台计算机上。
我们的应用系统使用的是SpringBoot+Mybatis-Plus的搭配,由于分表业务比较简单,就没有使用插件,而是使用Mybatis-Plus提供的 DynamicTableNameParser
处理器直接在程序中做动态路由。
由于官方文档在此处描述的并不是特别详细,所以写这篇博客作为记录。
开发
分表策略就不在此做说明了,网上已经有非常多不同的处理方式了,在这里主要阐述怎么样使用Mybatis-Plus提供的 ITableNameHandler
接口将不同表的做出不同处理。
实现 ITableNameHandler 接口
首先我们需要实现 ITableNameHandler
接口,该接口有两个方法(process, dynamicTableName),process()方法是做表名SQL处理的,该方法有默认实现,它依赖于dynamicTableName()方法,所以我们需要重写的方法便是dynamicTableName()方法
dynamicTableName()方法有三个入参,metaObject包括了元数据对象,sql是我们即将要执行的SQL,tableName则是我们执行的SQL表名称。我们需要修改的便是tableName。
下方我的代码逻辑是从DaysContext上下文对象中拿到事先设置的表名动态规则生成的表后缀,拼接上tableName便是我们需要动态路由的表名称了。
@Component
public class MyDynamicTableNameParser implements ITableNameHandler {
@Override
public String dynamicTableName(MetaObject metaObject, String sql, String tableName) {
DaysContext.Days days = DaysContext.get();
// 加上分表逻辑后缀
return tableName + "_" + days.getTableSuffix();
}
}
将配置注入到Mybatis-Plus配置中
接下来需要将我们的动态表名处理器 MyDynamicTableNameParser
配置到 PaginationInterceptor
对象中
@Configuration
public class MybatisPlusConfig {
private final MyDynamicTableNameParser myDynamicTableNameParser;
public MybatisPlusConfig(MyDynamicTableNameParser myDynamicTableNameParser) {
this.myDynamicTableNameParser = myDynamicTableNameParser;
}
/**
* 分页, 分表插件
*/
@Bean
public PaginationInterceptor paginationInterceptorMysql() {
// 分页
PaginationInterceptor page = new PaginationInterceptor();
page.setDialectType("mysql");
// 分表
dynamicTableNameParser(page);
return page;
}
/**
* 分表
*/
private void dynamicTableNameParser(PaginationInterceptor page) {
// 为指定表设置动态表名处理器
HashMap<String, ITableNameHandler> map = new HashMap<>(2);
map.put("sys_user", myDynamicTableNameParser);
map.put("sys_logs", myDynamicTableNameParser);
// 将需要处理的表添加到动态表名 SQL 解析器
DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
dynamicTableNameParser.setTableNameHandlerMap(map);
// 加入处理器链中
List<ISqlParser> iSqlParsers = new ArrayList<>();
iSqlParsers.add(dynamicTableNameParser);
page.setSqlParserList(iSqlParsers);
}
}
在dynamicTableNameParser()方法中,第一个代码块将需要动态路由的表通过K-V的形式配置我们刚编写的路由处理器对象。
第二个代码块中将我们添加的表名处理器设置到 Mybatis-Plus的 表名处理器 DynamicTableNameParser 中
第三个代码块将我们配置的表名处理器添加到Mybatis-Plus的处理器链中
通过上面的配置,我们就能够根据配置的路由规则,将配置的需要路由的表动态拼接上我们生成的后缀名了。
总结
框架做了很好的封装,整个过程还是非常顺利的,也顺利通过了测试。写这篇博客做个记录。