MybatisPlus拦截器如何实现数据表分表

 更新时间:2024年11月06日 09:29:12   作者:樘棣寂寂  
为了解决MySQL中大数据量的查询效率问题,采用水平拆分策略,通过取模运算确定表后缀,实现数据的有效管理,设计分表时,需利用线程变量存取请求参数,并通过拦截器确定操作的具体表名,从而优化数据处理性能,此方法适用于业务表数据量大或快速增长的场景

MybatisPlus拦截器实现数据表分表

很多项目都会存在一些数据量很大或者数据量增加很快的业务表,由于mysql的数据量达到一定量后会影响我们的查询效率,为了避免该类问题发生,我们需要在项目前期设计的时候针对这两类情况做一个分表的设计。

这里的分表指的是水平拆分(只是表名不同,其余字段都一致,主键id不允许重复),对某一个数字取模运算做为拆分后表的后缀名,具体要分多少张表可通过自己实际的项目情况确定。

首先创建请求参数传递的一个辅助类

/**
 * 请求参数传递辅助类
 */
public class RequestDataHelper {
    /**
     * 请求参数存取
     */
    private static final ThreadLocal<Map<String, Object>> REQUEST_DATA = new ThreadLocal<>();

    /**
     * 设置请求参数
     *
     * @param requestData 请求参数 MAP 对象
     */
    public static void setRequestData (Map<String, Object> requestData) {
        REQUEST_DATA.set(requestData);
    }

    /**
     * 获取请求参数
     *
     * @return 请求参数 MAP 对象
     */
    public static Map<String, Object> getRequestData () {
        return REQUEST_DATA.get();
    }
}

该辅助类主要作用有:

  • a.设置请求参数
  • b.将请求参数存取到线程变量中
  • c.获取请求参数

简单的说就是在涉及到需要分表的数据操作时,将请求参数放入线程变量中。

然后在拦截器里面获取这个参数,做特定的处理,找到我们具体要操作的那张表。

这里的请求参数大家可以把它理解成跟我们分表后的表名产生关联的数据。

这里面的线程变量是仅在当前线程下可使用的数据,与其他线程做隔离。

在本文中不做详细解释。

在涉及到分表的数据层操作前(Mybatisplus或者Mybatis增删改查数据前)

将请求参数放入线程变量

RequestDataHelper.setRequestData(Collections.singletonMap("studentId", param.getStudentId()));
        LambdaQueryWrapper<StudentRecordEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentRecordEntity::getStudentId, param.getStudentId());
        List<StudentRecordEntity> studentRecordEntityList = super.list(queryWrapper);

Mybatisplus 拦截器代码

/**
     * Mybatis plus 拦截器
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        //动态表插件
        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
            // 获取参数方法
            if (tableName.equalsIgnoreCase("t_student_record")) {
                Map<String, Object> paramMap = RequestDataHelper.getRequestData();
                long studentId= Long.parseLong(String.valueOf(paramMap.get("studentId")));
                int mod = (int) (studentId% 16);
                return tableName + "_" + mod;

            } else {
                return tableName;
            }
        });
        interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
        return interceptor;
    }

这里面t_student_record表就是要拆分的表,如果有多个,在if里面写多个。

studentId就是调用的时候传入线程变量的请求参数,对它%16就是分了16张表,根据实际业务情况,需要分多少张就把%后面的数字改为多少。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SQL PRIMARY KEY唯一标识表中记录的关键约束语句

    SQL PRIMARY KEY唯一标识表中记录的关键约束语句

    这篇文章主要为大家介绍了SQL PRIMARY KEY唯一标识表中记录的关键约束语句详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • MySQL多表关联查询相关练习题

    MySQL多表关联查询相关练习题

    这篇文章主要给大家介绍了关于MySQL多表关联查询的相关资料,在MySQL中JOIN语句是实现多表关联查询的关键,它可以将多个表格中符合条件的数据连接在一起,从而提供一个完整的查询结果,需要的朋友可以参考下
    2023-10-10
  • MySQL实现批量推送数据到Mongo

    MySQL实现批量推送数据到Mongo

    这篇文章主要为大家详细介绍了MySQL如何实现批量推送数据到Mongo,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
    2023-05-05
  • mysql 8.0.15 版本安装教程 连接Navicat.list

    mysql 8.0.15 版本安装教程 连接Navicat.list

    这篇文章主要为大家详细介绍了mysql 8.0.15 版本安装教程,连接Navicat.list,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • mysql创建存储过程实现往数据表中新增字段的方法分析

    mysql创建存储过程实现往数据表中新增字段的方法分析

    这篇文章主要介绍了mysql创建存储过程实现往数据表中新增字段的方法,结合实例形式对比分析了通过存储过程新增字段相关操作技巧,需要的朋友可以参考下
    2018-12-12
  • MySQL中关于case when的用法

    MySQL中关于case when的用法

    这篇文章主要介绍了MySQL中关于case when的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • Windows(x86,64bit)升级MySQL 5.7.17免安装版的详细教程

    Windows(x86,64bit)升级MySQL 5.7.17免安装版的详细教程

    这篇文章主要介绍了Windows(x86,64bit)升级MySQL 5.7.17免安装版的详细教程,需要的朋友可以参考下
    2017-02-02
  • Centos7下使用yum安装mysql数据库的详细教程(增强版)

    Centos7下使用yum安装mysql数据库的详细教程(增强版)

    这篇文章主要介绍了Centos7下使用yum安装mysql数据库的详细教程(增强版),非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-12-12
  • MySQL系列之三 基础篇

    MySQL系列之三 基础篇

    本文主要介绍了MySQL基础使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-07-07
  • SQL中Limit的用法及注意事项

    SQL中Limit的用法及注意事项

    LIMIT关键字是SQL中一个非常有用的工具,它可以用来限制查询结果返回的记录数量,实现数据的分页,或者从复杂查询中获取特定的记录,本文给大家介绍SQL中Limit的用法,感兴趣的朋友一起看看吧
    2025-04-04

最新评论