记录分库分表的分页查询

分库分表的分页查询。不同的业务场景可能不同。我只记录自己的分页方法

public PageAO<User> selectByPage(Filter filter, int page, int size) {
        //每页条数
        int pageSize = size < 1 ? 10 : size;
        //计算起始位置
        int pageIndex = page < 1 ? 0 : (page - 1) * pageSize;
        //记录查询数据条数时的,查询条数,可能动态变化,比如共需要十条数据,第一个表查询5条,则第二个表只需要查询5条即可
        int currentPageSize = pageSize;
        //统计所有分表,满足条件的总条数
        long total = 0;
        //返回结果集
        List<UserDo> respList = new ArrayList<>();
        //处理查询的条件
        param param = getParam(filter);
        //循环所有分表,依次查询
        for (int tableIndex = 0; tableIndex < dbProperties.getTableSize(); tableIndex++) {
        // 锁定分表,将当前查询置为一个具体表查询
        lockTaskTableIndex(tableIndex);
        //统计当前表满足条件的记录条数
        long count = mapper.countByParam(param);
        //释放分表,再需要查询数据时,再重新锁定分表
        releaseTaskTableIndex();
        //如当前表满足条件数为0,则直接跳过当前分表。不需要继续判断
        if (count == 0) {
            continue;
        }
        //将满足条件的记录条数统计到总数。统计所有分表
        total += count;
        //当前表统计结果减去起始位置结果为负数,则从当前表开始查询,否则顺序查询下一张表。如果为0则表示当前表数据刚好满足需要的总条数
        int index = pageIndex - Long.valueOf(count).intValue();
        //主要计算当前分表数是否满足,起始位置。如果为0,则表示截止当前分表,刚好满足limt跳过的数据条数。则跳过当前分表,从下一分表查询即可
        if (index >= 0) {
        //改变查询索引,比如查询第二页,起始索引为10,第一页满足6条,则第二页起始位置从10-6=4条开始
        pageIndex = index;
        continue;
        //如果需要的记录条数满足请求的页数,则不继续查询数据了。但需要继续循环分表,统计符合条件的总条数
        } else if (currentPageSize <= 0) {
        continue;
        }
        // 锁定分表,查询数据
        lockTaskTableIndex(tableIndex);
        //设置分页信息,起始位置,及条数,limit 1,10
        param.setCustomizePagination(pageIndex, pageSize);
        //若小于等于0,则需要开始查询数据
        List<UserDo> list = mapper.selectByParam(param);
        //将查询出来的数据,添加到集合等待最后返回
        respList.addAll(list);
        //若当前表记录条数不满足需要的页数,则需要查询下一张表,下一张表的起始位置为0
        pageIndex = 0;
        //列,每页需要十条,但当前表只获取了5条,则下一页只需要获取5条即可
        currentPageSize = pageSize - respList.size();
        //释放当前分表
        releaseTaskTableIndex();
        }
        //封装返回结果集
        return DbUtil.convert(respList, page, size, total, this::toUser);
        }

68fe300d572a46baa8409cc6e446265b.png

当前表统计结果减去起始位置结果为负数,则从当前表开始查询,否则顺序查询下一张表。若果结果集满足查询条数则返回数据,否则查询下一张表。且起始位置为0,至到满足结果集条数或分表查询完为止。 

 查询第一页:锁定第一张表,count条数为6。(0-6=-6)结果为负数,则从当前表开始查询,起始位置为0,size=10。查询结果条数为6不满足size10.
则查询下一张表,起始位置为0,查询条数为(10-6=4)以此类推

查询第二页:count第一张表结果为6。(10-6=4)不为负数,则查询第二张表。Count条数为9.(4-9=-5)结果为负数。则从第二张表开始查询
第二张表由索引下标4开始查询,size=10。最终查询结果为后五条。总记录条数为(10-5=5),由于查询记录条数不够。则取第三张表。记录条数不够的跳表。下标为0,查询条数为剩余的记录条数。(0,5) 

查询第三页。Count第一张表,记录条数为6,(20-6=14)结果不为负数,表示需要继续跳过,统计第二张表,记录条数为9(14-9=5)结果不为负数
继续跳过,count第三张表,记录条数为0(6-0=6)不为负数,继续跳过。统计第四张表,记录条数为15.(5-15=-10)结果为负数,则需要从当前表
开始查询,第四张表:limt 5,10。查询结果条数为10.(查询结果条数10-需要结果条数10=0)满足需要结果条数,返回结果数据 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Silence丶你的名字

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值