/**
* 合并两个库的数据,真分页
* @param pageNum 页码(从1开始)
* @param pageSize 页大小
* @param age 查询条件(示例)
* @return 分页结果
*/
public IPage<UserDTO> mergeUserPage(Integer pageNum, Integer pageSize, Integer age) {
// 1. 查询两个库的总条数(全局总条数)
Long db1Total = userDb1Mapper.selectUserTotal(age);
Long db2Total = userDb2Mapper.selectUserTotal(age);
Long total = db1Total + db2Total;
// 2. 计算全局分页参数(起始位置、结束位置)
long start = (pageNum - 1) * pageSize; // 全局起始索引(从0开始)
long end = start + pageSize; // 全局结束索引(不包含)
// 3. 分段查询两个库的数据(避免查询全量)
List<UserDTO> db1List = new ArrayList<>();
List<UserDTO> db2List = new ArrayList<>();
// 3.1 处理db1:计算需要从db1查询的条数
if (start < db1Total) {
// db1的查询起始位置:若start < db1Total,从start开始;否则db1无数据
long db1Start = Math.max(start, 0);
// db1的查询条数:最多取 end - db1Start,且不超过db1剩余条数
long db1Size = Math.min(end - db1Start, db1Total - db1Start);
if (db1Size > 0) {
// MyBatis-Plus分页:current=起始页(从1开始),size=条数
Page<UserDTO> db1Page = new Page<>((db1Start / pageSize) + 1, db1Size);
IPage<UserDTO> db1IPage = userDb1Mapper.selectUserPage(db1Page, age);
db1List = db1IPage.getRecords();
}
}
// 3.2 处理db2:计算需要从db2查询的条数
if (start < (db1Total + db2Total)) {
// db2的查询起始位置:若start < db1Total,从0开始;否则从 start - db1Total 开始
long db2Start = Math.max(start - db1Total, 0);
// db2的查询条数:最多取 end - (db1Total + db2Start),且不超过db2剩余条数
long db2Size = Math.min(end - (db1Total + db2Start), db2Total - db2Start);
if (db2Size > 0) {
Page<UserDTO> db2Page = new Page<>((db2Start / pageSize) + 1, db2Size);
IPage<UserDTO> db2IPage = userDb2Mapper.selectUserPage(db2Page, age);
db2List = db2IPage.getRecords();
}
}
// 4. 合并并排序(按创建时间降序,保证全局有序)
List<UserDTO> mergeList = new ArrayList<>();
mergeList.addAll(db1List);
mergeList.addAll(db2List);
// 按createTime排序(需保证两个库的时间格式一致)
mergeList = mergeList.stream()
.sorted(Comparator.comparing(UserDTO::getCreateTime).reversed())
.collect(Collectors.toList());
// 5. 裁剪当前页数据(极端场景:合并后条数超过pageSize,需裁剪)
List<UserDTO> currentPageList = mergeList.stream()
.skip(start)
.limit(pageSize)
.collect(Collectors.toList());
// 6. 构建分页结果
Page<UserDTO> resultPage = new Page<>();
resultPage.setCurrent(pageNum);
resultPage.setSize(pageSize);
resultPage.setTotal(total);
resultPage.setRecords(currentPageList);
return resultPage;
}
}