`

一种多数据源分页算法

    博客分类:
  • 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/c++ 分页式存储管理

    操作系统中的分页式存储管理是内存管理的一种策略,它的核心目标是解决主存与辅存之间的数据交换问题,以提高内存利用率和系统效率。在分页系统中,内存被划分为固定大小的页框,而程序则被分割为同样大小的页。这种...

    操作系统课设 分页式存储管理(内含OPT,FIFO,LRU,LFU四种算法,用到了线程)

    1. **最优淘汰法(Optimal Page Replacement Algorithm, OPT)**:这是一种理想化的算法,它总是能预测到未来哪个页面将最早被再次访问,从而提前替换掉它。在实际操作中,由于无法预知未来,所以通常用于理论分析和...

    jsp分页显示数据源代码

    本项目"jsp分页显示数据源代码"结合了JavaServer Pages (JSP) 和Servlet技术,以及MySQL数据库,实现了一个可运行的分页展示数据的实例。下面我们将详细探讨这个项目中的关键知识点。 首先,我们来了解JSP(Java...

    分页显示源程序、源代码

    在IT行业中,分页显示是一种常见的数据展示技术,特别是在处理大量数据时,如数据库查询结果、源代码浏览等场景。本资源提供的是一个与Java相关的分页显示源代码,旨在帮助学习者理解和实现分页功能。Java作为一种多...

    仿淘宝分页按钮效果简单美观易实用当分页JS控件

    分页控件是网页应用中一种用于管理大量数据的用户界面组件,它将一个长列表分割成多个可独立加载的部分,用户可以通过点击分页按钮来浏览不同的数据片段。这种控件可以有效地减少页面加载时间,提高网页性能,同时...

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

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

    vc6.0 实现分页显示的源文件

    TabControl是Visual C++中的一种容器控件,它允许在一个窗口内创建多个“选项卡”,每个选项卡可以包含不同的子窗口或控件。在分页显示的应用中,TabControl的每个选项卡可以视为一个独立的“页面”,用户可以通过...

    百度风格的ASP分页代码

    本示例中的"百度风格的ASP分页代码"就是一种实现方式,旨在模仿百度搜索引擎的分页效果。下面将详细解析这一知识点: 1. **ASP基础**:ASP是微软公司推出的一种服务器端脚本环境,用于创建动态交互式网页。它允许...

    JSP通用分页 把数据实行分页

    在Web开发领域,JSP(JavaServer Pages)是一种常见的服务器端技术,用于生成动态网页内容。本主题将探讨如何使用JSP实现通用的数据分页功能,这是一个非常实用的技术,尤其在处理大量数据时,可以提高网页加载速度...

    Pager(通过的分页工具类)

    分页是一种数据展示策略,将大量数据分成若干小部分,每次只加载和显示一部分,而不是一次性加载所有数据。这样可以减少内存占用,提高页面加载速度,同时使得用户能够更轻松地浏览和管理信息。 设计原则: 1. **...

    JSP页面数据列表的分页实现

    - **数据集**:指的是从数据库或其他数据源查询得到的所有数据集合。 - **每页显示记录数**(Page Size):每页展示的数据条数。 - **总记录数**(Total Records):数据集中总的记录数量。 - **总页数**(Total ...

    分页小程序

    在IT行业中,分页是一种常见的数据管理技术,特别是在网页和应用程序中,用于处理大量数据的显示。本项目“分页小程序”就是针对这一需求而设计的。它旨在提供一种高效、用户友好的方式来浏览和操作大数组或数据库中...

    JSP实现类似百度,google的分页

    在网页开发中,分页是一种常见的用户界面设计,它用于将大量数据分割成多个小块,以便用户可以逐步浏览和处理。在这个主题中,我们将深入探讨如何使用Java Server Pages(JSP)技术来实现类似百度或Google的高效、...

    操作系统算法源码 请求分页 页面置换 文件管理

    请求分页是一种内存管理技术,用于解决程序运行时所需的内存超过实际物理内存的问题。它将程序分割成固定大小的页,并在需要时从磁盘加载到内存中,称为页表的结构记录了页与内存块之间的映射关系。请求分页的关键...

    分页式存储管理

    最近最少使用算法是一种更合理的页面置换策略,它基于这样一个假设:如果一个数据项最近被访问过,那么它很可能马上又要被访问。因此,在发生缺页中断时,LRU算法会选择最近一段时间内未被访问过的页面作为淘汰对象...

    JS分页源代码,非常详细

    分页是大数据量展示时常用的一种优化手段,它可以将大量内容分割成多个小部分,便于用户逐页浏览,提高用户体验。 HTMLPage.htm可能是包含JavaScript分页功能的HTML页面示例,它展示了如何将JavaScript代码嵌入到...

    JSP分页事例源代码

    在Web开发中,数据量大的时候,分页是一种常见的优化用户体验的方法。这个事例源代码是基于JavaServer Pages(JSP)技术实现的,采用MVC(Model-View-Controller)设计模式,同时结合了过滤器和监听器功能,以实现...

    三大框架下分页源代码

    在IT行业中,分页是一种常见的数据展示方式,尤其在网页应用中,用于处理大量数据时,提高用户体验。这里我们讨论的是在三大框架(通常指的是Spring、Struts2和Hibernate)下实现分页的方法。 首先,从DAO层来看,...

    Jquery无刷新分页

    无刷新分页是一种网页设计技术,它允许用户在浏览数据列表时无需加载整个新页面就能切换到下一页或上一页,极大地提升了用户体验。jQuery是一个轻量级、高性能的JavaScript库,广泛用于简化DOM操作、事件处理和动画...

    模拟系统请求分页式存储管理

    在操作系统中,分页式存储管理是一种常用的内存管理方式,它将进程的虚拟内存分割成固定大小的块,称为页,而物理内存也被划分为相同大小的块,称为页框。这种管理方式使得进程和物理内存之间的地址转换变得简单且...

Global site tag (gtag.js) - Google Analytics