动态表名

注意:本教程使用的数据库脚本、数据模型和环境信息请参考 “MyBatis Plus环境准备” 章节,点击下载示例源码

本文将介绍 MyBatis Plus 的 DynamicTableNameInnerInterceptor 插件,使用该插件实现表名动态替换。

为什么需要动态表名?

当数据量比较大的时候,为了提高数据库操作的效率,尤其是查询的效率,其中一种解决方案就是将数据表拆分。 拆分的数据表,结构完全一致,只不过是表的名字,按照某种规律,而成为一组。

例如:日志表(log),我们可以根据年份选择表格,如:log_2018、log_2019、log_2020 等。其中,log_2018 表格只存放 2018 年的日志信息,其他年份类推。

DynamicTableNameInnerInterceptor 插件

MyBatis Plus 提供的 DynamicTableNameInnerInterceptor 插件就是用来解决动态表名。同时,还提供了 TableNameHandler 接口,该接口有一个 dynamicTableName() 方法,该方法返回新的表名称。接口代码定义如下:

package com.baomidou.mybatisplus.extension.plugins.handler;

/**
 * @author miemie
 * @since 3.4.0
 */
public interface TableNameHandler {
    /**
     * 生成动态表名
     * @param sql       当前执行 SQL
     * @param tableName 表名
     * @return String
     */
    String dynamicTableName(String sql, String tableName);
}

可以通过 DynamicTableNameInnerInterceptor 插件的 setTableNameHandlerMap(Map<String, TableNameHandler > map) 方法设置每个表对应的 TableNameHandler。在进行 SQL 操作时,sql 对应的表存在 TableNameHandler,则调用 dynamicTableName() 方法获得新的表名称,用新的表名称替换旧的表名称。例如:

MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 动态表名插件
DynamicTableNameInnerInterceptor dynamicTabNameInterceptor = new DynamicTableNameInnerInterceptor();
Map<String, TableNameHandler> tableNameHandlerMap = new HashMap<>();
tableNameHandlerMap.put("log", new TableNameHandler() {
    @Override
    public String dynamicTableName(String sql, String tableName) {
        // 将随机的从 log_2018、log_2019 和 log_2020 表中获取数据
        // 在实际业务中,这种实现没有什么实际意义
        String[] tableSuffix = {"2018", "2019", "2020"};
        return tableName + "_" + tableSuffix[(int)(Math.random() * tableSuffix.length)];
    }
});
dynamicTabNameInterceptor.setTableNameHandlerMap(tableNameHandlerMap);
interceptor.addInnerInterceptor(dynamicTabNameInterceptor);

示例代码

(1)配置 DynamicTableNameInnerInterceptor 插件,如下:

package com.hxstrive.mybatis_plus;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor paginationInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 动态表名插件
        DynamicTableNameInnerInterceptor dynamicTabNameInterceptor = new DynamicTableNameInnerInterceptor();
        Map<String, TableNameHandler> tableNameHandlerMap = new HashMap<>();
        tableNameHandlerMap.put("log", new TableNameHandler() {
            @Override
            public String dynamicTableName(String sql, String tableName) {
                String[] tableSuffix = {"2018", "2019", "2020"};
                return tableName + "_" + tableSuffix[(int)(Math.random() * tableSuffix.length)];
            }
        });
        dynamicTabNameInterceptor.setTableNameHandlerMap(tableNameHandlerMap);
        interceptor.addInnerInterceptor(dynamicTabNameInterceptor);
        return interceptor;
    }
}

(2)客户端代码,如下:

package com.hxstrive.mybatis_plus.plugins;

import com.hxstrive.mybatis_plus.mapper.LogMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
class PluginDemo5 {
    @Autowired
    private LogMapper mapper;

    @Test
    void contextLoads() {
        mapper.selectById(1);
    }
}

运行上面代码,将运行下面 sql 语句:

Preparing: SELECT log_id,summary,create_date FROM log_2019 WHERE log_id=?
Parameters: 1(Integer)

注意:上面代码中 LogMapper 和前面章节定义的 SimpleMapper一样,均继承自 BaseMapper。 


说说我的看法
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号