一、常用两种方法
分页时,根据页面大小(pageSize)和总行数(total),计算总页面数(totalPage)
法1
// 法1 总行数取余页面大小,等于0,则页数为整页数,否则有余数,则页数为正页数加一
int totalPage = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1);
法2(推荐,简洁)
int totalPage = (total + pageSize - 1) / pageSize;
法2推理过程如下:
- 特殊情况total = 0时,为0页
- total大于等于一页时
2.1 整除的情况下:total / pageSize 满足
2.2 有余数的情况下,就多加一页: total / pageSize + 1 等价于 (total + pageSize) / pageSize - total小于页面大小时,为1页
3.1 当total = 1时,total需要再加上整数x,才够一页,即(total + x) / pageSize,x ∈ [pageSize - 1, 2(pageSize - 1)]
3.2 当total = pageSize - 1时,total需要再加上整数x,才够一页,即(total + x) / pageSize,x ∈ [1, pageSize]
为了满足情况3.1、3.2,二者取交集,所以total需要加上整数 x ∈ [pageSize - 1, pageSize]
如果x取pageSize,会影响情况2.1造成页数多一页,不会影响情况2.2,故舍去
又因为pageSize - 1为 total 除以 pageSize 的最大余数,对total大于等于一页的两种情况均不影响,所以x应取pageSize - 1
所以综上所述:总页数totalPage = (total + pageSize - 1) / pageSize,代入total=0时,为0页,满足,证明完毕!
total / pageSize + 1等价于(total + pageSize) / pageSize: 取整(/ 二元操作符)是一个整体和另一个整体进行运算,不可化简,此处等价于有前提条件。
(total + pageSize - 1) / pageSize 不可化简成 (total - 1) / pageSize + 1,因为此处是取整,不是除法。
二、验证
total | pageSize | (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1) | (total + pageSize - 1) / pageSize |
---|---|---|---|
0 | 500 | 0 | 0 |
1 | 500 | 1 | 1 |
499 | 500 | 1 | 1 |
500 | 500 | 1 | 1 |
501 | 500 | 2 | 2 |
999 | 500 | 2 | 2 |
1000 | 500 | 2 | 2 |
代码如下:
int pageSize = 500;
int total = 0;
int p1 = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1);
int p2 = (total + pageSize - 1) / pageSize;
System.out.println("total=0, pageSize=500: p1=" + p1 + " p2=" + p2);
total = 1;
p1 = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1);
p2 = (total + pageSize - 1) / pageSize;
System.out.println("total=1, pageSize=500: p1=" + p1 + " p2=" + p2);
total = 499;
p1 = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1);
p2 = (total + pageSize - 1) / pageSize;
System.out.println("total=499, pageSize=500: p1=" + p1 + " p2=" + p2);
total = 500;
p1 = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1);
p2 = (total + pageSize - 1) / pageSize;
System.out.println("total=500, pageSize=500: p1=" + p1 + " p2=" + p2);
total = 501;
p1 = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1);
p2 = (total + pageSize - 1) / pageSize;
System.out.println("total=501, pageSize=500: p1=" + p1 + " p2=" + p2);
total = 999;
p1 = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1);
p2 = (total + pageSize - 1) / pageSize;
System.out.println("total=999, pageSize=500: p1=" + p1 + " p2=" + p2);
total = 1000;
p1 = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1);
p2 = (total + pageSize - 1) / pageSize;
System.out.println("total=1000, pageSize=500: p1=" + p1 + " p2=" + p2);
三、代码中分页/批处理
final int max_batch_size = 1000;
// 结果集
List<Map<String, Object>> result = new ArrayList<>();
// 参数,此参数可能有很多,sql中又使用了in,故分批处理
List<String> params = new ArrayList<>();
int totalPage = (max_batch_size + params.size() - 1) / max_batch_size;
for (int i = 0; i < totalPage; i++) {
int fromIndex = i * max_batch_size;
int toIndex = (i + 1) * max_batch_size;
toIndex = Math.min(toIndex, params.size());
result.add(xxxMapper.query(params.subList(fromIndex, toIndex)));
}