分库分表的分页查询。不同的业务场景可能不同。我只记录自己的分页方法
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);
}
当前表统计结果减去起始位置结果为负数,则从当前表开始查询,否则顺序查询下一张表。若果结果集满足查询条数则返回数据,否则查询下一张表。且起始位置为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)满足需要结果条数,返回结果数据