MybatisPlus设置动态表名

打印 上一主题 下一主题

主题 1541|帖子 1541|积分 4623


对于一些数据量比力大的表,为了进步查询性能,我们一般将表拆分成多张表,常见的是根据数据量,按年分表或者按月分表;分表固然太高了查询性能,但是在查询的时候,怎样才能查询执行分表数据呢,这里整理了一下,使用MybatisPlus设置动态表名的功能实现
增加MyBatisPlus配置类

  1. import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
  2. import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
  3. import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import java.util.HashMap;
  7. @Configuration
  8. public class MyBatisPlusConfig {
  9.     @Bean
  10.     public MybatisPlusInterceptor mybatisPlusInterceptor() {
  11.         MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
  12.         DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
  13.         HashMap<String, TableNameHandler> map = new HashMap<>();
  14.         map.put("my_test", (sql, tableName) -> DynamicTableTreadLocal.INSTANCE.getTableName());
  15.         
  16.         // 如果存在多张分表,则在下面添加多条记录
  17.         dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);
  18.         mybatisPlusInterceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
  19.         return mybatisPlusInterceptor;
  20.     }
  21. }
复制代码
方法剖析

MybatisPlusInterceptor

该插件是核心插件,如今署理了 Executor#query 和 Executor#update 和 StatementHandler#prepare 方法
方法属性

  
  1. private List<InnerInterceptor> interceptors = new ArrayList<>();
复制代码
InnerInterceptor接口

如今已有的功能:


  • 自动分页: PaginationInnerInterceptor
  • 多租户: TenantLineInnerInterceptor
  • 动态表名: DynamicTableNameInnerInterceptor
  • 乐观锁: OptimisticLockerInnerInterceptor
  • sql 性能规范: IllegalSQLInnerInterceptor
  • 防止全表更新与删除: BlockAttackInnerInterceptor
留意事项

使用多个功能需要留意次序关系,发起使用如下次序


  • 多租户,动态表名
  • 分页,乐观锁
  • sql 性能规范,防止全表更新与删除
总结: 对 sql 举行单次改造的优先放入,不对 sql 举行改造的末了放入
增加本地动态线程设置表名

  1. public enum DynamicTableTreadLocal {
  2.     INSTANCE;
  3.     private ThreadLocal<String> tableName = new ThreadLocal<>();
  4.     public String getTableName() {
  5.         return tableName.get();
  6.     }
  7.     public void setTableName(String tableName) {
  8.         this.tableName.set(tableName);
  9.     }
  10.     public void remove() {
  11.         tableName.remove();
  12.     }
  13. }
复制代码
DynamicTableTreadLocal类的作用是为每个线程提供一个独立的tableName变量。每个线程可以通过调用getTableName方法获取自己的tableName变量的值,也可以通过调用setTableName方法设置自己的tableName变量的值。如允许以保证每个线程都有自己独立的tableName变量,不会相互干扰。
ThreadLocal在该类中的作用

ThreadLocal是Java中的一个类,它提供了线程本地变量的功能。在DynamicTableTreadLocal类中,通过创建一个ThreadLocal对象tableName,每个线程都可以通过这个对象来获取和设置自己的tableName变量。ThreadLocal保证了每个线程都有自己独立的变量副本,不会被其他线程访问或修改。
ThreadLocal应用场景

ThreadLocal的应用场景主要是在多线程环境下,需要为每个线程维护独立的变量副本的情况下使用。例如,在Web应用中,每个请求都会被分配给一个线程举行处理,如果需要在处理请求的过程中生存一些状态信息,可以使用ThreadLocal来实现。另外,ThreadLocal还可以用于线程池、数据库连接池等场景,保证每个线程都有自己独立的资源。
表对应的的实体类配置

  1. @Data
  2. @TableName("my_test")
  3. @JsonInclude(JsonInclude.Include.NON_NULL)
  4. public class MyTest implements Serializable {
  5.     private static final long serialVersionUID = -65257563878624647L;
  6.     @TableId("uuid")
  7.     private String uuid;
  8.    
  9.     @JsonProperty("user_name")
  10.     @TableField("user_name")
  11.     private String userName;
  12. }
复制代码
在表对应的的实体类上,只需要配置没有分年代的表名@TableName("my_test")即可,无需指定分年代的表名;具体通过MyBatisPlusConfig类,根据DynamicTableTreadLocal类设置的表名自动切换要操作的表名
动态切换表的具体使用

设置表名

  1. DynamicTableTreadLocal.INSTANCE.setTableName("mytest_202401");
复制代码
获取表名

  1. DynamicTableTreadLocal.INSTANCE.getTableName();
复制代码
删除表名

  1. DynamicTableTreadLocal.INSTANCE.remove();
复制代码
末了总结

文章参考MyBatis-Plus官方文档,根据具体业务需求修改实现
官方文档地点

  1. https://baomidou.com/
复制代码
动态表名插件

  1. https://gitee.com/baomidou/mybatis-plus-samples/tree/master/mybatis-plus-sample-dynamic-tablename
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大号在练葵花宝典

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表