mybatis-plus实现动态表名

212 阅读1分钟

一、使用场景

  • 需要在表名后面动态添加时间,例: wiki_page,wiki_page_2025,wiki_page_2024
  • 需要调用的视图,例:查询与wiki_page同结构的v_wiki_page

二、实现

1、实现TableNameHandler的自定义实现

import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.List;

/**
 * 功能描述:<br>
 * 动态替换表名Handler
 */
public class ViewTableNameHandler implements TableNameHandler {

    private final List<String> ableTableNameList;

    public ViewTableNameHandler(String ...ableTableNames){
        this.ableTableNameList = Arrays.asList(ableTableNames);
    }

    //避免多线程数据冲突。所以使用ThreadLocal
    private static final ThreadLocal<String> VIEW_TABLE_NAME = new ThreadLocal<>();
    
    //设置请求线程的表名
    public static void setViewTableName(String vTableName){
        VIEW_TABLE_NAME.set(vTableName);
    }
    
    //删除当前请求线程的表名
    public static void removeViewTableName(){
        VIEW_TABLE_NAME.remove();
    }

    @Override
    public String dynamicTableName(String sql, String tableName) {
        //需要修改的表名再配置列表中,且传入的修改后表名不为空
        if(this.ableTableNameList.contains(tableName) && StringUtils.isNotBlank(VIEW_TABLE_NAME.get())){
            //按需编写表名设置逻辑
            return VIEW_TABLE_NAME.get();
        }
        return tableName;
    }
}

2、添加到MybatisPlus拦截器配置中

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //...其他拦截器

        //动态表名处理
        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        dynamicTableNameInnerInterceptor.setTableNameHandler(new ViewTableNameHandler("wiki_page"));
        interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
        return interceptor;
    }
}

3、使用

//设置查询表名
ViewTableNameHandler.setViewTableName("v_wiki_page");
//查询操作....
//移除查询表名
ViewTableNameHandler.removeViewTableName();