这个问题说起来挺难受的,假设表table1和table2是两个不同的表,但是基本该有的字段一致,除了有几个字段不同,由于历史的遗留的设计原因,不知道到你已经第几手代码
(此时你想骂娘,我也想。我就遇上了。)
奇葩的需求是:前端UI设计师要求一个列表页面同时要显示两表的数据(要分页)。
说白了就是后端实际两张表,前端UI设计师看来就是一张表的数据,呵呵,必须分页啊,两张表分页?难搞哦,话说来,分库分表中间件才会遇上的事情被你遇上了。好了,我们开干。
分析:
//①表示table1
//②表示table2
//假设某一次分页查询:pageSize = 5,currentPage = 1
//假设一:①有数据11条,pageSize = 5,currentPage = 1,①数据5条够了,不需要②来凑
//假设二:①有数据10条,pageSize = 5,currentPage = 1,①数据5条够了,不需要②来凑
//假设某一次分页查询:pageSize = 5,currentPage = 3
//假设三:①有数据11条,pageSize = 5,currentPage = 3,①数据1条不够了,需要②来凑4条
//假设四:①有数据10条,pageSize = 5,currentPage = 3,①数据不需要,全部在②里面5条
//假设某一次分页查询:pageSize = 5,currentPage = 4
//假设五:①有数据11条,pageSize = 5,currentPage = 4,不需要①来凑,全部在②里面5条
//假设六:①有数据10条,pageSize = 5,currentPage = 4,不需要①来凑,全部在②里面5条
//int countTable1 = 11;
//int countTable2 = 11;
// 11 - 5 * 1 = 6
// 11 - 5 * 2 = 1
// 11 - 5 * 3 = -4
// 11 - 5 * 4 = -9
// int countTable1 = 10;
// int countTable2 = 11;
// 10 - 5 * 1 = 5
// 10 - 5 * 2 = 0
// 10 - 5 * 3 = -5
// 10 - 5 * 4 = -10
代码按照分析的情况展开(部分关键代码):
//参数
//int currentPage
//int pageSize
//待返回的信息
List<Map<String, Object>> listAll = new ArrayList<>();
int listCount = 0;
Map<String, Object> back = new HashMap<>();
int countTable1 = `select count(*) from table1`;
int countTable2 = `select count(*) from table2`;
//检验:总数等于0,直接返回
listCount = countTable1 + countTable2;
if( listCount <= 0){
//无数据
back.put("list",listAll);
back.put("listCount",listCount);
return back;
}
//开始业务逻辑
int fillPage = countTable1 - pageSize * currentPage;
//是不是需要下一部分table2?
if(fillPage < 0){
//fillPage < 0 需要下一部分table2!
//转为正数
int fillPageTemp = -fillPage;
//需要下一部分table2多少?
if(fillPageTemp % pageSize == 0){
//********************************************
// 需要下一部分table2一整页:(全部在table2)
//********************************************
currentPage = currentPage - ((int)(countTable1 / pageSize));
currentPage = (currentPage - 1) * pageSize;
pageSize = pageSize;
listAll = `select * from table2 limit #{ currentPage} ,#{ pageSize}`
}else{
if(fillPageTemp < pageSize){
int currentPageOriginal = currentPage;
int pageSizeOriginal = pageSize;
//********************************************
//一部分table1
//********************************************
currentPage = currentPage;
currentPage = (currentPage - 1) * pageSize;
pageSize = pageSize - fillPageTemp;
List<Map<String, Object>> listTable1 = `select * from table1 limit #{ currentPage} ,#{ pageSize}`
//********************************************
//一部分table2
//********************************************
currentPageOriginal = currentPageOriginal - ((int)(countTable1 / pageSize));
currentPageOriginal = (currentPageOriginal - 1) * pageSize;
if(currentPageOriginal <= 0){ currentPageOriginal = 0;}
pageSizeOriginal = fillPageTemp;
List<Map<String, Object>> listTable2 = `select * from table2 limit #{ currentPageOriginal} ,#{ pageSizeOriginal}`
//合并
listAll.addAll(listTable1);
listAll.addAll(listTable2);
}else{
//********************************************
//(全部在table2)
//********************************************
currentPage = currentPage - ((int)(countTable1 / pageSize));
currentPage = (currentPage - 1) * pageSize;
//向前移动
currentPage = currentPage - (countTable1 - pageSize * ((int)(countTable1 / pageSize)));
pageSize = pageSize;
listAll = `select * from table2 limit #{ currentPage } ,#{ pageSize }`
}
}
}else{
//********************************************
//TODO fillPage >= 0 当前table1部分足够了:(数据全部在table1)
//********************************************
currentPage = (currentPage - 1) * pageSize;
pageSize = pageSize;
listAll = `select * from table1 limit #{ currentPage} ,#{ pageSize}`
}
//返回
back.put("list",listAll);
back.put("listCount",listCount);
return back;