欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > MybatisPlus设置动态表名

MybatisPlus设置动态表名

2024/10/24 1:50:54 来源:https://blog.csdn.net/aaalk1001/article/details/140599727  浏览:    关键词:MybatisPlus设置动态表名

在这里插入图片描述

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

增加MyBatisPlus配置类

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;@Configuration
public class MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();HashMap<String, TableNameHandler> map = new HashMap<>();map.put("my_test", (sql, tableName) -> DynamicTableTreadLocal.INSTANCE.getTableName());// 如果存在多张分表,则在下面添加多条记录dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);mybatisPlusInterceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);return mybatisPlusInterceptor;}}
方法解析
MybatisPlusInterceptor

该插件是核心插件,目前代理了 Executor#queryExecutor#updateStatementHandler#prepare 方法

方法属性
private List<InnerInterceptor> interceptors = new ArrayList<>();
InnerInterceptor接口

目前已有的功能:

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

使用多个功能需要注意顺序关系,建议使用如下顺序

  • 多租户,动态表名
  • 分页,乐观锁
  • sql 性能规范,防止全表更新与删除

总结: 对 sql 进行单次改造的优先放入,不对 sql 进行改造的最后放入

增加本地动态线程设置表名

public enum DynamicTableTreadLocal {INSTANCE;private ThreadLocal<String> tableName = new ThreadLocal<>();public String getTableName() {return tableName.get();}public void setTableName(String tableName) {this.tableName.set(tableName);}public void remove() {tableName.remove();}
}

DynamicTableTreadLocal类的作用是为每个线程提供一个独立的tableName变量。每个线程可以通过调用getTableName方法获取自己的tableName变量的值,也可以通过调用setTableName方法设置自己的tableName变量的值。这样可以保证每个线程都有自己独立的tableName变量,不会相互干扰。

ThreadLocal在该类中的作用

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

ThreadLocal应用场景

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

表对应的的实体类配置

@Data
@TableName("my_test")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MyTest implements Serializable {private static final long serialVersionUID = -65257563878624647L;@TableId("uuid")private String uuid;@JsonProperty("user_name")@TableField("user_name")private String userName;
}

在表对应的的实体类上,只需要配置没有分年月的表名@TableName("my_test")即可,无需指定分年月的表名;具体通过MyBatisPlusConfig类,根据DynamicTableTreadLocal类设置的表名自动切换要操作的表名

动态切换表的具体使用

设置表名
DynamicTableTreadLocal.INSTANCE.setTableName("mytest_202401");
获取表名
DynamicTableTreadLocal.INSTANCE.getTableName();
删除表名
DynamicTableTreadLocal.INSTANCE.remove();

最后总结

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

官方文档地址
https://baomidou.com/
动态表名插件
https://gitee.com/baomidou/mybatis-plus-samples/tree/master/mybatis-plus-sample-dynamic-tablename

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com