数据分页模块系列 (二) 完美封装PageModel实现分页模块

先说一下框架分页技术,在我们之前那个高校项目中使用DWZ实现的分页用了自定义标签使用起来也比较方便,除了DWZ很多框架已经给我们做好了分页我们需要做的仅仅是把一些分页参数传给我们的框架,俗话说你用别人的东西就得按着别人的来,得按着别人的框架进行布局了、传参了等等,这样灵活性大大降低,况且感觉使用框架频繁的一些软件一般是一些管理类型的,对界面的美观方便需求并不是很高,工整、能用就可以,然而呢,还有些界面需要灵活配置分页按钮、分页条等,这就需要把类似于这样的功能封装起来。

分页的模块很多人都在写都在用,大体上的思路是一致的也不是什么新的技术,不同的是看谁封装的更灵活对于本系统更好用这是不同的地方。在我们那个基础系统里面长海封装了一个分页,只要在页面上引入一个自定义标签即可,使得开发人员实现这个功能非常的容易。

分页需求:

1.同样一个分页模块如果拿到了别人系统里面是不是可以呢

2.分页样式经常更换(和界面分离,只等着美工画好界面给我就好)

3.接收一个后台查询出来的list对象或数组对象等

如果想要随意更换分页样式需要引入分页模板,其实就是一个html类型的文件以inc结尾,需要自己提前写好,下面是这个模板代码,利用模板真正做到了后台开发同美工分离,美工如果更换了前台样式后台不用改动一点代码就完成了

	<span>总课程数:$page.total </span>
                    <span>总页数:$page.totalPage </span>
                    <span class="pag_01">当前第<a>$page.currentPageNumber</a>页</span>
                    <span class="pag_02"><a href="#" onClick="changePage(1,$page.pageSize)">[首页]</a>
					 <a href="#" onclick="changePage(${page.previousPageNumber},$page.pageSize)">[上一页]</a>
					 <a href="#" onclick="changePage(eval($page.nextPageNumber),$page.pageSize)">[下一页]</a>
					 <a href="#" onclick="changePage($page.totalPage,$page.pageSize)">[尾页]</a></span>
                    <span id="tail_span">转到<input id="go_page" type="text" class="put_03" />页<input value="go" type="button" onclick="jumpPage($page.totalPage,$page.pageSize);"></span>

PageModel 类的代码

package com.zhjy.zydc.web.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.io.Serializable;
import java.io.StringWriter;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.context.Context;
import org.apache.velocity.app.Velocity; 

/**
 * @author lilongsheng
 * @return 描述显示结果集的页面
 */
public class Page implements Serializable {

	//每一页显示几天记录
	public static final int PAGE_SIZE = 8;
	public static final int PAGE_SIZE_SMALL = 5;
	public static final int PAGE_SIZE_NORMAL = 8;
	public static final int PAGE_SIZE_BIG = 8;
	public static final int PAGE_SIZE_BIGGER = 20;
	public static final int PAGE_SIZE_BIGGEST = 50;

	public static final int PAGE_NUMBER_FIRST = 1;
	/**
	 * 空白页面
	 */
	public static final Page EMPTY_PAGE =
		new Page(Collections.EMPTY_LIST, 0, false);

	/**
	 * 结果集列表
	 */
	List objects;

	/**
	 * 开始记录号,从0开始
	 */
	public int start;
	/**
	 * 结束记录号
	 */
	public int end;
	/**
	 * 显示在页面开始记录号,从1开始
	 */
	public int viewStart;
	/**
	 * 显示在页面结束记录号
	 */
	public int viewEnd;
	/**
	 * 是否有上一页的开关
	 */
	public boolean hasPrevious;
	/**
	 * 上一页的页码
	 */
	public int previousPageNumber;
	/**
	 * 是否有下一页的开关
	 */
	public boolean hasNext;
	/**
	 * 下一页的页码
	 */
	public int nextPageNumber;
	/**
	 * 一共有多少行记录
	 */
	public int total;
	/**
	 * 一共有多少页
	 */
	public int totalPage;
	/**
	 * 当前是第几页
	 */
	public int currentPageNumber;
	/**
	 * 每页有多少行
	 */
	public int pageSize;

    /**
     * 得到分页的起始纪录
     * @param pageNo
     * @param max
     * @return
     */
    public static int selectSavNo(int pageNo, int max) {
        int savNo = 0;
        savNo = (pageNo - 1) * max;
        return savNo;
    }

	/**
	 * 构造器,创建一个页面,不分页
	 * @param: objects 结果集
	 */
	public Page(List objects) {
		this.objects = new ArrayList(objects);
		this.currentPageNumber = 1;
		this.pageSize = objects.size();
		this.total = objects.size();
		if (total == 0)
			this.currentPageNumber = 0;
		else
			autoCalculate();
	}

	/**
	 * 构造器,创建页面
	 * @param: objects 结果集
	 * @param: s 开始记录号,从0开始
	 * @param: hasNext 是否有下一页的开关
	 */
	public Page(List objects, int s, boolean hasNext) {
		this(objects,s,hasNext,0);
	}

	/**
	 * 构造器,创建页面
	 * @param: objects 结果集
	 * @param: s 开始记录号,从0开始
	 * @param: hasNext 是否有下一页的开关
	 * @param: total 一共有多少行记录
	 */
	public Page(List objects, int s, boolean hasNext, int total) {
		this(objects,s,PAGE_SIZE,hasNext,total);
	}

	/**
	 * 构造器,创建页面
	 * @param: l 结果集
	 * @param: s 开始记录号,从0开始
	 * @param: size 每页有多少行
	 * @param: hasNext 是否有下一页的开关
	 * @param: total 一共有多少行记录
	 */
	public Page(List objects, int s, int size, boolean hasNext, int total) {
		this.objects = new ArrayList(objects);

		this.currentPageNumber = s / size + 1;
		this.pageSize = size;
		this.total = total;
		System.out.println("查询出的总记录数是:"+total);
		if (total == 0)
		{
			System.out.println("查询出的总记录数是否为等于 0:"+total);
			this.currentPageNumber = 0;
		}else
		{
			System.out.println("是否执行了判断上一页、下一页:");
			autoCalculate();
		}
	}

	/**
	 * 构造器,创建页面
	 * @param: objects 结果集
	 * @param: currentPageNumber 当前是第几页
	 * @param: pageSize 每页有多少行
	 * @param: total 一共有多少行记录
	 */
	public Page(List objects, int currentPageNumber, int pageSize, int total) {
		this.objects = objects;
		this.currentPageNumber = currentPageNumber;
		this.pageSize = pageSize;
		this.total = total;

		if (total == 0)
		{
			this.currentPageNumber = 0;

		}else
		{
			autoCalculate();

		}
	}

	/**
	 * @author lls
	 * @return 计算当前页号
	 *
	 */
	private void autoCalculate() {

		start = (currentPageNumber - 1) * pageSize;
		if(pageSize>this.objects .size()){
			end = this.objects .size()-1;
		}else{
			end = start + pageSize-1;
		}
		if (end >= total) {
			end = total - 1;
		}
		//显示在页面开始记录号,从1开始
		viewStart = start + 1;
		//显示在页面结束记录号
		viewEnd = end + 1;
		totalPage = (total + pageSize - 1) / pageSize;

		//如果当前页小于等于1
		if (currentPageNumber <= 1) {
			//不能再上一页,并设置当前页为1
			hasPrevious = false;
			currentPageNumber = 1;
		} else if(hasPrevious) {
			//当前页号减一
			currentPageNumber = currentPageNumber - 1;
		}
		//如果当前页号大于等于总页数
		if (currentPageNumber >= totalPage) {
			//设置下一页不可用
			hasNext = false;

			System.out.println(currentPageNumber);
			currentPageNumber = totalPage;
			System.out.println(currentPageNumber);

		} else if(hasNext){
			//当前页号加一
			currentPageNumber = currentPageNumber + 1;
		}
	}

	/**
	 * 获得结果集
	 * @return: List 结果集
	 */
	public List getList() {
		return this.objects;
	}

	/**
	 * 获得显示在页面的开始记录号,从1开始
	 * @return: int 显示在页面的开始记录号
	 */
	public int getViewStart() {
		return viewStart;
	}
	/**
	 * 获得显示在页面的结束记录号
	 * @return: int 显示在页面的结束记录号
	 */
	public int getViewEnd() {
		return viewEnd;
	}
	/**
	 * 是否有下一页
	 * @return: boolean 是否有下一页的开关
	 */
	public boolean hasNextPage() {
		return hasNext;
	}
	/**
	 * 是否有上一页
	 * @return: boolean 是否有上一页的开关
	 */
	public boolean hasPreviousPage() {
		return hasPrevious;
	}
	/**
	 * 获得上一页的页码
	 * @return: int 上一页的页码
	 */
	public int getPreviousPageNumber() {
		return previousPageNumber;
	}
	/**
	 * 获得下一页的页码
	 * @return: int 下一页的页码
	 */
	public int getNextPageNumber() {
		return nextPageNumber;
	}
	/**
	 * 获得结果集中记录总行数
	 * @return: int 一共有多少行记录
	 */
	public int getTotal() {
		return total;
	}
	/**
	 * 获得总页数
	 * @return: int 一共有多少页
	 */
	public int getTotalPage() {
		return totalPage;
	}
	/**
	 * 获得当前页码
	 * @return: int 当前页码
	 */
	public int getCurrentPageNumber() {
		return currentPageNumber;
	}
	/**
	 * 获得每页多少行记录
	 * @return: int 页大小
	 */
	public int getPageSize() {
		return pageSize;
	}
	/**
	 * 获得下一页在结果集中开始的记录号,从0开始
	 * @return: int 下一页在结果集中开始的记录号
	 */
	public int getStartOfNextPage() {
		return start + PAGE_SIZE;
	}
	/**
	 * 获得上一页在结果集中开始的记录号,从0开始
	 * @return: int 下一页在结果集中开始的记录号
	 */
	public int getStartOfPreviousPage() {
		return Math.max(start - PAGE_SIZE, 0);
	}

	/**
	 * 根据页号和记录数得到起始记录
	 * @param pageNo
	 * @param pageSize
	 * @return
	 */
	public static int getStartNumber(int pageNo, int pageSize) {
		int startNumber = 0;
		startNumber = (pageNo - 1) * pageSize;
		return startNumber;
	}

    /**
     * hidden条件
     * @param result
     */
    private void getHiddenInfo(StringBuffer result){
        result.append("<input type=\"hidden\" name=\"pageNumber\">");
        result.append("<input type=\"hidden\" name=\"pageSize\">");

    }
    /**
     * @tuthod :lilongsheng
     * @param  StringBuffer
     * @result js字符串
     */
	private void  getJavaScript(StringBuffer result){

	    //js代码开始标记
       result.append("<SCRIPT LANGUAGE=\"JavaScript\">");
       //上一页、下一页等按钮的点击事件,该事件同模板中的对应
       result.append(" function changePage(pageNumber,pageSize)")
        		    .append("{")
			        .append(" document.forms[0].pageNumber.value = pageNumber;")
			        .append(" document.forms[0].pageSize.value = pageSize;")
			        .append(" document.forms[0].submit(); ")
			        .append("}");
       //跳转按钮的点击事件
       result.append(" function jumpPage(totalPage,pageSize)")
		    	.append("{")
		        .append(" var pageNumber = parseFloat(document.getElementById(\"go_page\").value);")
		        .append(" if (pageNumber > totalPage){")
		        .append(" pageNumber = totalPage;}")
		        .append(" if (pageNumber < 1){")
		        .append(" pageNumber = 1;}")
		        .append(" document.forms[0].pageNumber.value = pageNumber;")
		        .append(" document.forms[0].pageSize.value = pageSize;")
		        .append(" document.forms[0].submit();")
		        .append("}");
       //js代码结尾标记
        result.append("</SCRIPT>");
    }

	/**
	 * @parameter 按钮模板的名称
	 * @return    页面跳转按钮和相应的按钮的的js事件
	 */
	public String getPageBar_(String t_name)throws Exception{
		//存储字符串
		StringBuffer result = new StringBuffer();

	    //网页面上加载js代码,分为对应上一页、下一页等按钮的点击事件
		getJavaScript(result);
		//hidden
	    getHiddenInfo(result);
		//分页按钮“上一页”“下一页”等从模板中加载
		Template template = Velocity.getTemplate("WEB-INF/classes/"+t_name,"utf-8");
 		Context context = new VelocityContext();
		context.put("page", this);
		StringWriter writer =new StringWriter();
		template.merge(context,writer);
		writer.flush();
		result.append(writer.toString());
		return result.toString();
	}
}

该分页类中有个getPageBar_(string t_name)方法,这个方法完成了动态加载分页模板并打印到页面上,用着很方便,一些按钮的单击等事件也是通过pagemodel类写到页面上,可以说界面上只需要引入一个pageModel即可完成分页所有的功能,其余的代码一点不用写了,大大提高了开发效率。

工作感悟:

工作时对某些知识理解的要深刻、理解的到位一些,毕竟给你一个东西如果你理解是模棱两可的,那你就不能写出东西来不知道除了错误不知道怎么去改正,工作中学习的新知识相比在学校的确很少,很很多事情需要做拿不出几天时间来专门学习什么,如果想学习也只能晚上下班后利用自己的时间扩展学习一下,也感觉自己需要学习的东西还很多,正在学习中……

数据分页模块系列 (二) 完美封装PageModel实现分页模块,码迷,mamicode.com

时间: 2024-10-13 06:15:25

数据分页模块系列 (二) 完美封装PageModel实现分页模块的相关文章

面向对象系列二(封装)

只需要最简单的操作就能实现一系列复杂的功能,是做一个个技术攻克的目的.一台精密仪器,一架家用电器,一个小米手机,这些可能我们都在用,或者用过.它们的内部都无比的复杂,使用了各种各样的配件,运用了极多的原理和知识.我们在使用的时候都具有相同的感受:简单.方便.太好了!面对原本复杂的东西,我们却能通过简单介绍就能运用自如,甚至有的能无师自通,这都为什么?这就用到了面向对象的封装性. 面向对象的封装性就是将复杂的处理封装在"盒子"的内部,只凭借装外壳的少量的按钮或键盘就能轻松实现功能.哦,原

数据分页处理系列之二:HBase表数据分页处理

  HBase是Hadoop大数据生态技术圈中的一项关键技术,是一种用于分布式存储大数据的列式数据库,关于HBase更加详细的介绍和技术细节,朋友们可以在网络上进行搜寻,笔者本人在接下来的日子里也会写一个HBase方面的技术专题,有兴趣的朋友们可以稍微的期待一下.不过本章节的重点是介绍下HBase表数据的分页处理,其他的就不多说了. 首先说一下表数据分页中不可回避的一个指标:总记录数.在关系数据库中很容易统计出记录总数,但在HBase中,这却是一个大难题,至少在目前,朋友们根本不要奢望能够通过类

数据分页处理系列之三:Neo4j图数据分页处理

  首先简单介绍下Neo4j,Neo4j是一个高性能的NOSQL图形数据库,它将结构化数据存储在网络上而不是表中,它是一个嵌入式的.基于磁盘的.具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)而不是表中.Neo4j也可以被看做是一个高性能的图引擎,该引擎具有成熟数据库的所有特性. Neo4j中涉及到几个关键的实体对象,分别是Node(节点).Relationship(关系).Path(路径).Direction(关系方向).RelationshipType

MP实战系列(十二)之封装方法详解(续二)

继续MP实战系列(十一)之封装方法详解(续一)这篇文章之后. 此次要讲的是关于查询. 查询是用的比较多的,查询很重要,好的查询,加上索引如鱼得水,不好的查询加再多索引也是无济于事. 1.selectById()方法 演示示例: UserEntity user = ud.selectById(33); System.out.println(user.getEmail()); 简单的说明: 如果是在MyBatis中,需要再对应的xml编写这样的sql select column1,column2..

Influx Sql系列教程九:query数据查询基本篇二

前面一篇介绍了influxdb中基本的查询操作,在结尾处提到了如果我们希望对查询的结果进行分组,排序,分页时,应该怎么操作,接下来我们看一下上面几个场景的支持 在开始本文之前,建议先阅读上篇博文: 190813-Influx Sql系列教程八:query数据查询基本篇 0. 数据准备 在开始查询之前,先看一下我们准备的数据,其中name,phone为tag, age,blog,id为field > select * from yhh name: yhh time age blog id name

OkHttp框架从入门到放弃,解析图片使用Picasso裁剪,二次封装OkHttpUtils,Post提交表单数据

OkHttp框架从入门到放弃,解析图片使用Picasso裁剪,二次封装OkHttpUtils,Post提交表单数据 我们这片博文就来聊聊这个反响很不错的OkHttp了,标题是我恶搞的,本篇将着重详细的分析,探索OkHttp这个框架的使用和封装 一.追其原理 Android系统提供了两种HTTP通信类 HttpURLConnection HttpClient Google推荐使用HttpURLConnection,这个没必要多说,事实上,我这篇写的应该算是比较晚了,很多优秀的博文都已经提出了这些观

Android-Volley网络通信框架(二次封装数据请求和图片请求(包含处理请求队列和图片缓存))

1.回想 上篇 使用 Volley 的 JsonObjectRequest 和 ImageLoader 写了 电影列表的样例 2.重点 (1)封装Volley 内部 请求 类(请求队列,数据请求,图片请求,图片缓存) (2)封装 Response.Listener 和 Response.ErrorListener 回调函数 (3)用法 3.文件夹介绍 3.1 GsonRequset.java 自己定义Gson请求,直接将 Json字符串  实例化为 对象 3.2 VolleyApplicatio

数据分页处理系列之一:Oracle表数据分页检索SQL

  关于Oracle数据分页检索SQL语法,网络上比比皆是,花样繁多,本篇也是笔者本人在网络上搜寻的比较有代表性的语法,绝非本人原创,贴在这里,纯粹是为了让"数据分页专题系列"看起来稍微完整和丰满一些,故先在这里特别声明一下,以免招来骂声一片! 先介绍两个比较有代表性的数据分页检索SQL实例. 无ORDER BY排序的写法.(效率最高) (经过测试,此方法成本最低,只嵌套一层,速度最快!即使检索的数据量再大,也几乎不受影响,速度依然!) SELECT * FROM (SELECT RO

Android 完美对BaseAdapter进行二次封装

在开发列表的界面的时候经常会重写BaseAdapter,利用网上的知识点技巧,自己对它进行了二次封装方便以后在项目中再次使用.使用起来方便得很. 当然如何你看了代码可以的话,也可以对ExpandableListAdapter同样的封装! 使用自定义BaseAdapter: package com.cyy.myandroid; import android.content.Context; import android.provider.ContactsContract.Data; import