分库分表的分页查询。不同的业务场景可能不同。我只记录自己的分页方法
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,10param.setCustomizePagination(pageIndex, pageSize);//若小于等于0,则需要开始查询数据List<UserDo> list = mapper.selectByParam(param);//将查询出来的数据,添加到集合等待最后返回respList.addAll(list);//若当前表记录条数不满足需要的页数,则需要查询下一张表,下一张表的起始位置为0pageIndex = 0;//列,每页需要十条,但当前表只获取了5条,则下一页只需要获取5条即可currentPageSize = pageSize - respList.size();//释放当前分表releaseTaskTableIndex();}//封装返回结果集return DbUtil.convert(respList, page, size, total, this::toUser);}
当前表统计结果减去起始位置结果为负数,则从当前表开始查询,否则顺序查询下一张表。若果结果集满足查询条数则返回数据,否则查询下一张表。且起始位置为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)满足需要结果条数,返回结果数据