当前位置: 代码网 > it编程>编程语言>Java > MybatisPlus拦截器如何实现数据表分表

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

2024年11月06日 Java 我要评论
mybatisplus拦截器实现数据表分表很多项目都会存在一些数据量很大或者数据量增加很快的业务表,由于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张表,根据实际业务情况,需要分多少张就把%后面的数字改为多少。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com