数据分表Mybatis Plus动态表名最优方案的探索

PRIMARY KEY (`id`)

)

COMMENT=‘学生表’

COLLATE=‘utf8_general_ci’

ENGINE=InnoDB

;




Student 实体类与student表是一一对应的关系,如果我们希望将学员表按照月份进行分表,比如:student\_202206、student\_202207、student\_202208,即产生了\*\*「一个实体类及其Mapper需要操作多个数据库分月表,这种情况在Mybatis plus下我们该如何操作数据呢?」\*\* 其实方法有很多,我将我实践中总结出的最优方案给大家进行说明。



[]( )二、动态表名处理器接口实现

----------------------------------------------------------------------



为了处理上述类似的问题,mybatis plus提供了动态表名处理器接口`TableNameHandler`,我们只需要实现这个接口,并将这个接口应用配置生效,即可实现动态表名。



> 需要注意的是:

> 

> *   在mybatis plus 3.4版本之前,动态表名处理器接口是`ITableNameHandler`, 需要配合mybatis plus分页插件一起使用才能生效。我们这里只介绍3.4版本之后的实现方式。

>     

> *   在mybatis plus 3.4.3.2 作废该的方式:dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map); 大家如果见到这种方式实现的动态表名,也是过时的实现方法,新版本中该方法已经删除。

>     



经过我一段时间的实践总结,我的实现类如下(基于mybatis plus 3.4.3.2之后的版本):



import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;

import java.util.Arrays;

import java.util.List;

/**

  • 按月份参数,组成动态表名

*/

public class MonthTableNameHandler implements TableNameHandler {

//用于记录哪些表可以使用该月份动态表名处理器(即哪些表按月分表)

private List<String> tableNames;

//构造函数,构造动态表名处理器的时候,传递tableNames参数

public MonthTableNameHandler(String ...tableNames) {

    this.tableNames = Arrays.asList(tableNames);

}



//每个请求线程维护一个month数据,避免多线程数据冲突。所以使用ThreadLocal

private static final ThreadLocal<String> MONTH_DATA = new ThreadLocal<>();

//设置请求线程的month数据

public static void setData(String month) {

    MONTH_DATA.set(month);

}

//删除当前请求线程的month数据

public static void removeData() {

    MONTH_DATA.remove();

}



//动态表名接口实现方法

@Override

public String dynamicTableName(String sql, String tableName) {

    if (this.tableNames.contains(tableName)){

        return tableName + "_" + MONTH_DATA.get();  //表名增加月份后缀

    }else{

        return tableName;   //表名原样返回

    }

}

}




大家先对上面的代码有一个基础了解,看了下面的测试过程,再回头看上面的代码中的注释,就比较好理解了。表名处理器写好了之后,我们要让它生效,还需要做如下的配置。配置内容照葫芦画瓢就可以了。需要关注的部分,我都已经给大家添加了注释。



@Configuration

@MapperScan(“com.zimug”)

public class MybatisPlusConfig {

@Bean

public MybatisPlusInterceptor mybatisPlusInterceptor() {

    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

    DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();

    dynamicTableNameInnerInterceptor.setTableNameHandler(

            //可以传多个表名参数,指定哪些表使用MonthTableNameHandler处理表名称

            new MonthTableNameHandler("student","teacher") 

    );

    //以拦截器的方式处理表名称

    interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);

    //可以传递多个拦截器,即:可以传递多个表名处理器TableNameHandler

    //interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);

    return interceptor;

}

}




[]( )三、测试实现效果

-----------------------------------------------------------------



首先创建一个StudentMapper ,默认情况下StudentMapper 只能操作student表,不能操作student\_YYYYMM表。



最后

腾讯T3大牛总结的500页MySQL实战笔记意外爆火,P8看了直呼内行

腾讯T3大牛总结的500页MySQL实战笔记意外爆火,P8看了直呼内行


首先创建一个StudentMapper ,默认情况下StudentMapper 只能操作student表,不能操作student_YYYYMM表。




# 最后

[外链图片转存中...(img-rkT5SYoL-1714720006109)]

[外链图片转存中...(img-qhMgvwtK-1714720006110)]

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/topics/618154847)收录**
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis-Plus是一个基于MyBatis的增强工具,它提供了许多方便的功能,其中包括动态表名的支持。通过使用MyBatis-Plus提供的DynamicTableNameInnerInterceptor拦截器,可以在运行动态替换SQL语句中的表名。 使用MyBatis-Plus实现动态表名有以下几个作用: 1. 实现数据分表数据分区:可以根据特定的规则生成动态表名,例如按照分表或按照业务冷热数据分离后将数据存储在不同的表中。 2. 隐藏数据表名:在某些情况下,为了安全或其他目的,可能需要隐藏数据库的表名。使用DynamicTableNameInnerInterceptor可以将表名进行动态替换,从而达到隐藏表名的效果。 3. 提高系统的可扩展性:通过动态表名解析器,可以将不同的数据表或数据库实例进行解耦,从而提高系统的可扩展性。例如,可以将一个大型的数据库系统分成多个小型的数据库实例,然后通过动态表名解析器将SQL语句分发到不同的实例中。 4. 简化代码开发:使用DynamicTableNameInnerInterceptor,可以避免在代码中硬编码SQL语句中的表名,从而简化代码的开发和维护。特别是在应对表结构频繁变化的场景下,使用该拦截器能够更快速地实现表名变更,从而降低维护成本。 因此,通过使用MyBatis-Plus的DynamicTableNameInnerInterceptor拦截器,可以实现mybatis-plus动态表名的功能,并带来诸多好处。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【mybatis-plus系列】动态表名](https://blog.csdn.net/qyj19920704/article/details/130010294)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [mybatis-plus动态表名实现](https://blog.csdn.net/zhangsuhua0702/article/details/122807303)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值