`

一种多数据源分页算法

    博客分类:
  • java
 
阅读更多

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

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;
	}
}




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

0
1
分享到:
评论
9 楼 asialee 2012-09-11  

大家谁可以给一个view的例子,但是有一种情况,比如张三去登陆,看到的是张三的数据,李四登陆,看到的是李四的数据,这个view怎么建立,还请指教。
8 楼 asialee 2012-09-11  

这个东西需求比较特殊的产物,去各个系统区抓取数据,但是为了安全期间,这些数据不允许在任何地方缓存,所以数据库建立view的情况也是不可取的。
7 楼 asialee 2012-09-11  
xiaokang1582830 写道
多数据源码不是这样弄的,我很想知道什么样的项目会出现这样的情况?

我们项目就用到了,去各个系统区抓取数据,但是为了安全期间,这些数据不允许在任何地方缓存,所以数据库建立view的情况也是不可取的。
6 楼 asialee 2012-09-11  
kerenbing 写道
如果翻页期间数据发生变化呢??????

翻页期间数据发生变化确实是有这个问题,这个东西是免不了的。
5 楼 kerenbing 2012-09-11  
如果翻页期间数据发生变化呢??????
4 楼 defungo 2012-09-11  
不可用,还不如建view呢
3 楼 lianglaiyang 2012-09-11  
可不可以在一个库中建立一个VIEW呢,这样跟操作我们普通的表没有任何两样。
2 楼 xiaokang1582830 2012-09-11  
多数据源码不是这样弄的,我很想知道什么样的项目会出现这样的情况?
1 楼 wukele 2012-09-11  
如果要排序的话,不是完蛋了。呵呵

相关推荐

    C语言实现 + 存储管理实验 + CPP源程序 + 实现页表的数据结构、分页式内存空间的分配及回收(建议采用位图法)页面置换算法

    要求实现:页表的数据结构、分页式内存空间的分配及回收(建议采用位图法)、地址重定位、页面置换算法(从FIFO,LRU,NRU中任选一种)。 提示:可先用动态申请的方式申请一大块空间,然后假设该空间为内存区域,对该...

    操作系统大报告——存储管理实验报告+包含程序源程序(实现请求式分页管理)+数百字个人心得+程序运行截图

    要求实现:页表的数据结构、分页式内存空间的分配及回收(建议采用位图法)、地址重定位、页面置换算法(从FIFO,LRU,NRU中任选一种)。 提示:可先用动态申请的方式申请一大块空间,然后假设该空间为内存区域,对该...

    操作系统课程设计--存储管理 源代码及完整报告

    请求页式管理是一种常用的虚拟存储管理技术。本设计的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。 (1)通过随机数产生一个指令序列,共320条...

    《计算机操作系统》期末复习指导

    操作系统(Operating System,OS),是一种软件,属于系统软件; 1、科普的观点 操作系统是计算机系统的管理和控制中心,它依照设计者制定的各种调度策略组织和管理计算机系统资源,使之能高效地运行。 2、功能...

    JAVA上百实例源码以及开源项目源代码

    2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。...

    北语15春《计算机科学导论》作业3.doc

    伪代码是一种用来书写程序或描述算法时使用的非正式、透明的表述方法。它是一 种编程语言。 A. 错误 B. 正确 -----------------选择: 3. COBOL是世界上最早出现的计算机高级程序设计语言。 A. 错误 B. 正确 ------...

    GoodProject Maven Webapp.zip

    5、场景对话的功能介绍:通过场景对话模块,开发者可快速搭建满足于不同场景下业务需求的多轮上下文对话,并实现对话式交互同自有产品业务、数据库以及第三方数据源的对接,实现产品服务体验升级。[2] 6、NLP知识库...

    java开源包1

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包11

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包2

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包3

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包6

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包5

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包10

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包4

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包8

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包7

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包9

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

Global site tag (gtag.js) - Google Analytics