一种多数据源分页算法

[size=medium][color=blue]
以前开发一个系统,需要去多个系统去取数据,简单期间,比如a,b,c 三个系统,然后抓取过来,每页显示10条,比如a系统的总记录数是10,b是15,c是8条,起先的时候要去这三个系统去查总记录数,但是翻页的时候,有的时候就不需要去各个系统都取了,比如第一页,只要去a系统取数据就可以了,第二页到b系统取10条记录,第三页是在b系统取5条记录,在c系统取5条记录,第四页去c系统取3条记录。
之前在网上找过,但是没有找到,后来就自己写了一个算法,可以完美的解决这个问题,直接上代码吧。
[/color][/size]

package com.xxx.pc.common.pager;

import java.util.ArrayList;
import java.util.List;

import com.xxx.pc.util.ProcessCenterConstants;

public class PageBeanFactory {
public final static int PAGE_MAX_SHOW_RECORDS = ProcessCenterConstants.DEFAULT_PAGE_SIZE;

public final static int NO_DATA = -1;
public final static int NOT_REQ = -2;

public static int[] getPageIndex(int[] maxRecords, int pageNum) {
// 第一页强制发送请求,用来获取最大值
if(pageNum == 1){
return initRets(maxRecords.length);
}

// 如果页码大于最大页码,则调整为最大页码
int fixPageNum = fixPageNum(maxRecords,pageNum);

// 第一页强制发送请求,用来获取最大值
if(fixPageNum == 1){
return initRets(maxRecords.length);
}


int[] returns = generateRets(maxRecords,fixPageNum);

// 标记不用发送请求的PageBean
fixNoDataRets(maxRecords,fixPageNum,returns);

return returns;
}

private static int[] generateRets(int[] maxRecords, int pageNum){
int maxPagesLength = maxRecords.length;
int hasDisplayed = (pageNum - 1) * PAGE_MAX_SHOW_RECORDS;

int[] returns = new int[maxPagesLength];

// 计算从什么地方翻页,并计算从什么地方要借数据
int i = 0;
for (; i < maxPagesLength; i++) {
hasDisplayed -= maxRecords[i];
if (hasDisplayed < 0) {
break;
}
}

for (int j = 0; j < maxPagesLength; j++) {
if (j < i) {
returns[j] = NO_DATA;
} else if (j == i) {
returns[j] = maxRecords[j] + hasDisplayed;
} else {
returns[j] = 0;
}
}

return returns;
}

private static int fixPageNum(int[] maxPages,int pageNum){
// 负数处理
if(pageNum <= 0){
return 1;
}

int total = 0;
for(int totalItem : maxPages){
total += totalItem;
}

int maxPage = total / PAGE_MAX_SHOW_RECORDS;
if(total % PAGE_MAX_SHOW_RECORDS != 0){
maxPage++;
}
if(pageNum > maxPage){
pageNum = maxPage;
}
return pageNum;
}


private static void fixNoDataRets(int[] maxPages, int pageNum,int[] returns) {
int maxPagesLength = maxPages.length;
int shoudDisplayed = pageNum * PAGE_MAX_SHOW_RECORDS;

int total = 0;
int i = 0;
for(; i < maxPagesLength; i++){
total += maxPages[i];
if(total >= shoudDisplayed){
break;
}
}

for(int j = i + 1; j < maxPagesLength; j++){
returns[j] = NOT_REQ;
}
}

private static int[] initRets(int maxLength){
int[] returns = new int[maxLength];
for(int i = 0; i < maxLength; i++){
returns[i] = 0;
}
return returns;
}

public static List<PageBean> create(int currentPage,int[] totals){
List<PageBean> pageBeans = new ArrayList<PageBean>();

int[] starts = getPageIndex(totals,currentPage);

for(int startItem : starts){
PageBean pageBean = new PageBean();
pageBean.setStartRecords(startItem);
pageBean.setMaxRecords(PAGE_MAX_SHOW_RECORDS);

pageBeans.add(pageBean);
}

return pageBeans;
}

}




package com.xxx.pc.common.pager;


import java.util.Map;

public class PageBean implements java.io.Serializable{
private static final long serialVersionUID = 7233650799588141948L;

private Map<String,Object> parameterMap; //生成分页时所带的参数键值对
private int startRecords = 0; //当前页数
private Integer maxRecords = PageBeanFactory.PAGE_MAX_SHOW_RECORDS; //一次查询的最大记录数
private int recordsCount = -1;

public PageBean() {}

public PageBean(int startRecords, Integer maxRecords) {
this.startRecords = startRecords;
this.maxRecords = maxRecords;
}

public Map<String, Object> getParameterMap() {
return parameterMap;
}
public void setParameterMap(Map<String, Object> parameterMap) {
this.parameterMap = parameterMap;
}
public int getStartRecords() {
return startRecords;
}

public void setStartRecords(int startRecords) {
this.startRecords = startRecords;
}

public Integer getMaxRecords() {
return maxRecords;
}
public void setMaxRecords(Integer maxRecords) {
this.maxRecords = maxRecords;
}

public int getRecordsCount() {
return recordsCount;
}
public void setRecordsCount(int recordsCount) {
this.recordsCount = recordsCount;
}
}



[size=large][color=blue]
算法就不仔细讲了,比较大的一个原则是根据当前页,计算前一页应该展示多少条数据,计算每个数据源的起始记录数,一种是一个数据源没有数据了,一个是还不需要发请求。

[/color][/size]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值