zoukankan      html  css  js  c++  java
  • 传统分页功能的实现

    之前一直认为分页是很繁琐的事情,随着时间的积累,这一次再次接触到分页功能,思路清晰了许多,其实分页无非就是根据页面的显示信息获取分页的几个值,大体上这些值也可以分类的:

    比如:页面传递的值或者默认的值;通过查询数据库的内容来获取的值;通过推导公式计算出来的值。

    (其实推导都是很简单的,只不过一提公式脑袋就大了,这是典型的不动脑的习惯,我本人属于此类,呵呵,所以大家还是多动脑,动脑,脑袋越动越灵活。)

    下面我们分析关于分页所需要哪些内容:其实基本上所有网页的分页都是大同小异的,或许我们有时候会有很多分页工具封装好了这些分页内容,比如mybatis的pageHelper类,直接封装好了分页信息,我们直接拿来用即可。

    但是明白了分页的最基本的原理,这些分页工具会起到画龙点睛的作用。下面我们开看看具体的分页信息:

    1、创建一个pageBean类:封装分页所需要的几个字段,这个类是为了代码复用,因为分页这个功能很多模块可能都会涉及到,到时候我们直接调用即可。

    首先我们看一个页面:

    这是一个分页的典型的图片,基本很多分页都是基于此来开发的,下面看下有多少分页字段:

    首先分页是对什么进行分页:页面要显示数据列表,而这些数据列表需要分页显示。所以我们要获取这些数据列表,然后加上分页的信息,将数据列表实现分段。

    即字段:

    recordList 每个页面显示的记录的列表。(这里涉及到每页都是从多少条记录开始显示的)

    总记录数是多少:recordCount

    我们看到页次:当前页/总共的页数   即 currentPage  /  pageCount

    每页显示的条数:pageSize

    另外我们看到我们想看哪一页就点击哪一页,总共要显示多少个页码,是都显示还是只显示一部分页码(这里又有一种方案),想跳转到哪一页就跳转到哪一页。

    根据上面的分析所得:分页的信息就是这些,接下来就是如何获取这些信息对应的数据的值,然后将此pageBean封装好这些信息然后反馈到页面,页面获取到这些信息进行显示。

    这里我们分三类:

    (1)页面传递的或者默认可以设置的字段:每页显示条数:pageSize  (可以默认自己设置多少值) ;当前页currentPage (通常默认为第一页)

    (2)需要查询数据库获取的字段的值:

                  显示列表的总记录数recordCount:SELECT COUNT(*) FROM table  WHERE 条件

                  加上分页后获取当前页面显示的记录的条数recordList:即每页页面显示的数据列表:

                 

    getSession().createQuery(//
    "FROM Reply r WHERE r.topic= ? ORDER BY r.postTime ")
    .setParameter(0,topic)
    .setFirstResult((pageNum-1)*10)

    注意这里有隐含的信息:比如我们设置每页显示10条记录,总共33条记录,第一页显示0--10记录数,第二页显示10--20,第三页显示30---40;即么每页显示10条。

    所以这里设置每页的开始记录就是:(pageNum-1)*10


    .setMaxResults(pageSize)
    .list();

      (3)获取到上面这些字段后,我们分析下如何通过公式计算剩下的字段:

    总共多少页:pageCount,

    页码开始的索引页beginPageIndex,页面结束的索引:endPageIndex(为什么要设置这两个字段呢,因为我们要进行列表的显示)

      

    //计算剩余的三个值,根据公式进行计算
    pageCount=(recordCount+pageSize-1)/pageSize;
    /*计算开始页索引和结束页索引:这里我们定义总共显示10个页码。分几种情况
    * 第一:当总共页数pageCount不足10页的时候,则显示全部页码
    * 第二:当总共页数超过10页时,则显示当前页的前4页和当前页的后5页。
    * 但是这里又有两种情况:如果总共有11页,当前页是3,则3-4=-1,这是不可以的,
    * 即当前面的页面少于4个时,这个时候显示前十页。
    * 同理:当后面的页面不足5个时,显示后10页。
    */

    if (pageCount<=10) {
    beginPageIndex=1;
    endPageIndex=pageCount;
    }else{
    beginPageIndex=currentPage-4;
    endPageIndex=currentPage+5;
    if (beginPageIndex-4<1) {
    beginPageIndex=1;
    endPageIndex=10;
    }
    if (endPageIndex>pageCount) {
    beginPageIndex=currentPage-10+1;
    endPageIndex=pageCount;
    }

    }

    }

     最后一步就是将封装好内容的pageBean传递到页面:页面获取响应的值

    2、修改jsp页面信息

    这里主要是注意struts2标签内部使用OGNL表达式,在HTML标签里面或者标签体使用EL表达式。

    OGNL用%{}  EL表达式用${}获取。

    3、具体代码如下:

    package cn.itcast.oa.domain;
    
    import java.util.List;
    
    public class PageBean {
    //主要是对分页的几个字段属性进行封装,这些字段都可以根据jsp页面来进行推断出来
    	//这些可以页码获取
    	private int currentPage;//当前页码
    	private int pageSize;//每页显示多少条记录
    	
    	//这些可以数据库获取
    	private List recordList;//本页的数据列表
    	private int recordCount;//总记录数
    	
    	//这些可以根据上面的计算得到
    	private int pageCount;//总共多少页
    	private int beginPageIndex;//页码的开始索引
    	private int endPageIndex;//页码的结束索引
    	
    	
    	public PageBean(int currentPage, int pageSize, List recordList, int recordCount) {
    		super();
    		this.currentPage = currentPage;
    		this.pageSize = pageSize;
    		this.recordList = recordList;
    		this.recordCount = recordCount;
    		
    		
    		//计算剩余的三个值,根据公式进行计算
    		pageCount=(recordCount+pageSize-1)/pageSize;
    		/*计算开始页索引和结束页索引:这里我们定义总共显示10个页码。分几种情况
    		 * 第一:当总共页数pageCount不足10页的时候,则显示全部页码
    		 * 第二:当总共页数超过10页时,则显示当前页的前4页和当前页的后5页。
    		 *      但是这里又有两种情况:如果总共有11页,当前页是3,则3-4=-1,这是不可以的,
    		 *           即当前面的页面少于4个时,这个时候显示前十页。
    		 *          同理:当后面的页面不足5个时,显示后10页。
    		 */
    		
    		if (pageCount<=10) {
    			beginPageIndex=1;
    			endPageIndex=pageCount;
    		}else{
    			beginPageIndex=currentPage-4;
    			endPageIndex=currentPage+5;
    			if (beginPageIndex-4<1) {
    				beginPageIndex=1;
    				endPageIndex=10;	
    			}
    			if (endPageIndex>pageCount) {
    				beginPageIndex=currentPage-10+1;
    				endPageIndex=pageCount;		
    			}
    			
    		}
    		
    	}
    	public int getCurrentPage() {
    		return currentPage;
    	}
    	public void setCurrentPage(int currentPage) {
    		this.currentPage = currentPage;
    	}
    	public int getPageSize() {
    		return pageSize;
    	}
    	public void setPageSize(int pageSize) {
    		this.pageSize = pageSize;
    	}
    	public List getRecordList() {
    		return recordList;
    	}
    	public void setRecordList(List recordList) {
    		this.recordList = recordList;
    	}
    	public int getRecordCount() {
    		return recordCount;
    	}
    	public void setRecordCount(int recordCount) {
    		this.recordCount = recordCount;
    	}
    	public int getPageCount() {
    		return pageCount;
    	}
    	public void setPageCount(int pageCount) {
    		this.pageCount = pageCount;
    	}
    	public int getBeginPageIndex() {
    		return beginPageIndex;
    	}
    	public void setBeginPageIndex(int beginPageIndex) {
    		this.beginPageIndex = beginPageIndex;
    	}
    	public int getEndPageIndex() {
    		return endPageIndex;
    	}
    	public void setEndPageIndex(int endPageIndex) {
    		this.endPageIndex = endPageIndex;
    	}	
    }
    

     

    //因为页面是要获取的是关于分页的pageBean这个类,页面获取里面的值,所以这里要想办法查询出pageBean这里面的字段的值
    	@Override
    	public PageBean getPageBeanByTopic(int pageNum, int pageSize, Topic topic) {
    	List list=getSession().createQuery(//
    				"FROM Reply r WHERE r.topic= ? ORDER BY r.postTime ")
    		        .setParameter(0,topic)
    		        .setFirstResult((pageNum-1)*10)
    		        .setMaxResults(pageSize) 
    		        .list();
    	Long count=(Long) getSession().createQuery(
    			"SELECT COUNT(*) FROM Reply r WHERE r.topic= ? ")
    		    .setParameter(0,topic)
    			.uniqueResult();
    	
    		return new PageBean(pageNum, pageSize, list, count.intValue());
    	}
    

      步骤应该是这样:先分析了类的字段,然后从数据库中查询中部分字段,然后将部分字段带入公式计算剩下的字段。

    这里使用了根据部分字段来写构造方法,然后service在调用这个构造方法,计算公式。

    看下jsp页面的代码:

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <html>
    <head>
    	<title>查看主题:${topic.title}</title>
        <%@ include file="/WEB-INF/jsp/public/commons.jspf" %>
    	<link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/style/blue/forum.css" />
    	<script language="javascript" src="${pageContext.request.contextPath}/script/fckeditor/fckeditor.js" charset="utf-8"></script>
        <script type="text/javascript">
    		$(function(){
    			var fck = new FCKeditor("content");
    			fck.Width = "90%";
    			fck.ToolbarSet = "bbs";
    			fck.BasePath = "${pageContext.request.contextPath}/script/fckeditor/";
    			fck.ReplaceTextarea();
    		});
        </script>
    </head>
    <body>
    
    <!-- 标题显示 -->
    <div id="Title_bar">
        <div id="Title_bar_Head">
            <div id="Title_Head"></div>
            <div id="Title"><!--页面标题-->
                <img border="0" width="13" height="13" src="${pageContext.request.contextPath}/style/images/title_arrow.gif"/> 查看主题
            </div>
            <div id="Title_End"></div>
        </div>
    </div>
    
    <!--内容显示-->	
    <div id="MainArea">
    	<div id="PageHead"></div>
    	<center>
    		<div class="ItemBlock_Title1" style=" 98%">
    			<font class="MenuPoint"> > </font>
    			<s:a action="forum_list">论坛</s:a>
    			<font class="MenuPoint"> > </font>
    			<s:a action="forum_show?id=%{#topic.forum.id}">${topic.forum.name}</s:a>
    			<font class="MenuPoint"> >> </font>
    			帖子阅读
    			<span style="margin-left:30px;">
    				<s:a action="topic_addUI?forumId=%{#topic.forum.id}">
    					<img align="absmiddle" src="${pageContext.request.contextPath}/style/blue/images/button/publishNewTopic.png"/>
    				</s:a>
    			</span>
    		</div>
    		
    		<div class="ForumPageTableBorder dataContainer" datakey="replyList">
    		
    			<!--显示主题标题等-->
    			<table width="100%" border="0" cellspacing="0" cellpadding="0">
    				<tr valign="bottom">
    				<td width="3" class="ForumPageTableTitleLeft"> </td>
    					<td class="ForumPageTableTitle"><b>本帖主题:${topic.title}</b></td>
    					<td class="ForumPageTableTitle" align="right" style="padding-right:12px;">
    						<s:a cssClass="detail" action="reply_addUI?topicId=%{#topic.id}">
    							<img border="0" src="${pageContext.request.contextPath}/style/images/reply.gif" />
    							回复
    						</s:a>
    						<a href="moveUI.html"><img border="0" src="${pageContext.request.contextPath}/style/images/edit.gif" />移动到其他版块</a>
    						<a href="#" onClick="return confirm('要把本主题设为精华吗?')"><img border="0" src="${pageContext.request.contextPath}/style/images/topicType_1.gif" />精华</a>
    						<a href="#" onClick="return confirm('要把本主题设为置顶吗?')"><img border="0" src="${pageContext.request.contextPath}/style/images/topicType_2.gif" />置顶</a>
    						<a href="#" onClick="return confirm('要把本主题设为普通吗?')"><img border="0" src="${pageContext.request.contextPath}/style/images/topicType_0.gif" />普通</a>
    					</td>
    					<td width="3" class="ForumPageTableTitleRight"> </td>
    				</tr>
    				<tr height="1" class="ForumPageTableTitleLine"><td colspan="4"></td></tr>
    			</table>
    
    			<!-- ~~~~~~~~~~~~~~~ 显示主帖(主帖只在第1页显示) ~~~~~~~~~~~~~~~ -->
    			<s:if test="currentPage==1">
    			<div class="ListArea">
    				<table border="0" cellpadding="0" cellspacing="1" width="100%">
    					<tr>
    						<td rowspan="3" width="130" class="PhotoArea" align="center" valign="top">
    							<!--作者头像-->
    							<div class="AuthorPhoto">
    								<img border="0" width="110" height="110" src="${pageContext.request.contextPath}/style/images/defaultAvatar.gif" 
    									onerror="this.onerror=null; this.src='${pageContext.request.contextPath}/style/images/defaultAvatar.gif';" />
    							</div>
    							<!--作者名称-->
    							<div class="AuthorName">${topic.author.name}</div>
    						</td>
    						<td align="center">
    							<ul class="TopicFunc">
    								<!--操作列表-->
    								<li class="TopicFuncLi">
    									<a class="detail" href="${pageContext.request.contextPath}/BBS_Topic/saveUI.html"><img border="0" src="${pageContext.request.contextPath}/style/images/edit.gif" />编辑</a>
    									<a class="detail" href="#" onClick="return confirm('确定要删除本帖吗?')"><img border="0" src="${pageContext.request.contextPath}/style/images/delete.gif" />删除</a>
    								</li>
    								<!-- 文章的标题 -->
    								<li class="TopicSubject">
    									${topic.title}
    								</li>
    							</ul>
    						</td>
    					</tr>
    					<tr><!-- 文章内容 -->
    						<td valign="top" align="center">
    							<div class="Content">${topic.content}</div>
    						</td>
    					</tr>
    					<tr><!--显示楼层等信息-->
    						<td class="Footer" height="28" align="center" valign="bottom">
    							<ul style="margin: 0px;  98%;">
    								<li style="float: left; line-height:18px;"><font color=#C30000>[楼主]</font>
    									${topic.postTime}
    								</li>
    								<li style="float: right;"><a href="javascript:scroll(0,0)">
    									<img border="0" src="${pageContext.request.contextPath}/style/images/top.gif" /></a>
    								</li>
    							</ul>
    						</td>
    					</tr>
    				</table>
    			</div>
    			</s:if>
    			<!-- ~~~~~~~~~~~~~~~ 显示主帖结束 ~~~~~~~~~~~~~~~ -->
    
    
    			<!-- ~~~~~~~~~~~~~~~ 显示回复列表 ~~~~~~~~~~~~~~~ -->
    			<s:iterator value="recordList" status="status">
    			<div class="ListArea template">
    				<table border="0" cellpadding="0" cellspacing="1" width="100%">
    					<tr>
    						<td rowspan="3" width="130" class="PhotoArea" align="center" valign="top">
    							<!--作者头像-->
    							<div class="AuthorPhoto">
    								<img border="0" width="110" height="110" src="${pageContext.request.contextPath}/style/images/defaultAvatar.gif" 
    									onerror="this.onerror=null; this.src='${pageContext.request.contextPath}/style/images/defaultAvatar.gif';" />
    							</div>
    							<!--作者名称-->
    							<div class="AuthorName">${author.name}</div>
    						</td>
    						<td align="center">
    							<ul class="TopicFunc">
    								<!--操作列表-->
    								<li class="TopicFuncLi">
    									<a class="detail" href="${pageContext.request.contextPath}/BBS_Topic/saveUI.html"><img border="0" src="${pageContext.request.contextPath}/style/images/edit.gif" />编辑</a>
    									<a class="detail" href="#" onClick="return confirm('确定要删除本帖吗?')"><img border="0" src="${pageContext.request.contextPath}/style/images/delete.gif" />删除</a>
    								</li>
    								<!-- 文章表情与标题 -->
    								<li class="TopicSubject">
    									${title}
    								</li>
    							</ul>
    						</td>
    					</tr>
    					<tr><!-- 文章内容 -->
    						<td valign="top" align="center">
    							<div class="Content">${content}</div>  
    						</td>
    					</tr>
    					<tr><!--显示楼层等信息-->
    						<td class="Footer" height="28" align="center" valign="bottom">
    							<ul style="margin: 0px;  98%;">
    								<li style="float: left; line-height:18px;"><font color=#C30000>[${(currentPage-1)*pageSize + status.count}楼]</font>
    									${postTime}
    								</li>
    								<li style="float: right;"><a href="javascript:scroll(0,0)">
    									<img border="0" src="${pageContext.request.contextPath}/style/images/top.gif" /></a>
    								</li>
    							</ul>
    						</td>
    					</tr>
    				</table>
    			</div>
    			</s:iterator>
    			<!-- ~~~~~~~~~~~~~~~ 显示回复列表结束 ~~~~~~~~~~~~~~~ -->
    		</div>
    
    		<!--分页信息-->
    		<div id=PageSelectorBar>
    			<div id=PageSelectorMemo>
    				页次:${currentPage}/ ${pageCount} 页  
    				每页显示:${pageSize}条  
    				总记录数:${recordCount}条
    			</div>
    			<div id=PageSelectorSelectorArea>
    			
    				<a href="javascript:gotoPage(1)" title="首页" style="cursor: hand;">
    					<img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/firstPage.png"/>
    				</a>
    				<!-- 注意EL表达式是用在外面,OGNL表达式是用在struts标签的内部,标签内 -->
    				<s:iterator begin="%{beginPageIndex}" end="%{endPageIndex}" var="num" >
    				<!-- var属性的对象的值存在了map中,所以用#获取-->
    				<s:if test="#num==currentPage">
    				    <span class="PageSelectorNum PageSelectorSelected">${num}</span>
    			 </s:if>
    				<!-- 非当前页 --> 
    				<s:else>
    				   <span class="PageSelectorNum" style="cursor: hand;" onClick="gotoPage(${num});">${num}</span>
    				</s:else>
    				</s:iterator>
    				
    				
    				<a href="javascript:gotoPage(${pageCount})" title="尾页" style="cursor: hand;">
    					<img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/lastPage.png"/>
    				</a>
    				
    				转到:
    				<select onchange="gotoPage(this.value)" id="_pn" >
    				   <s:iterator begin="1" end="%{pageCount}" var="num">
    				     <option  value="${num}">${num}</option>
    				   </s:iterator>
    				</select>
    				<script type="text/javascript">
    				   $("#_pn").val("${currentPage}");
    				</script>
    			
    			</div>
    		</div>
    				<!-- 这里有问题,页面跳转不过来 -->
    		<script type="text/javascript">
    		     function gotoPage(pageNum){
    		    	 window.location.href="topic_show.action?id=${id}&pageNum="+pageNum;
    		    	 
    		     }
    		</script>
    
    
    		<div class="ForumPageTableBorder" style="margin-top: 25px;">
    			<table width="100%" border="0" cellspacing="0" cellpadding="0">
    				<tr valign="bottom">
    					<td width="3" class="ForumPageTableTitleLeft"> </td>
    					<td class="ForumPageTableTitle"><b>快速回复</b></td>
    					<td width="3" class="ForumPageTableTitleRight"> </td>
    				</tr>
    				<tr height="1" class="ForumPageTableTitleLine">
    					<td colspan="3"></td>
    				</tr>
    			</table>
    		</div>
    	</center>
    			
    	<!--快速回复-->
    	<div class="QuictReply">
    	<form action="">
    		<div style="padding-left: 3px;">
    			<table border="0" cellspacing="1" width="98%" cellpadding="5" class="TableStyle">
    				<tr height="30" class="Tint">
    					<td width="50px" class="Deep"><b>标题</b></td>
    					<td class="no_color_bg">
    						<input type="text" name="title" class="InputStyle" value="回复:昨天发现在表单里删除的图片" style="90%"/>
    					</td>
    				</tr>
    				<tr class="Tint" height="200">
    					<td valign="top" rowspan="2" class="Deep"><b>内容</b></td>
    					<td valign="top" class="no_color_bg">
    						<textarea name="content" style=" 95%; height: 300px"></textarea>
    					</td>
    				</tr>
    				<tr height="30" class="Tint">
    					<td class="no_color_bg" colspan="2" align="center">
    						<input type="image" src="${pageContext.request.contextPath}/style/blue/images/button/submit.PNG" style="margin-right:15px;"/>
    					</td>
    				</tr>
    			</table>
    		</div>
    	</form>
    	</div>
    </div>
    
    <div class="Description">
    	说明:<br />
    	1,主帖只在第一页显示。<br />
    	2,只有是管理员才可以进行“移动”、“编辑”、“删除”、“精华”、“置顶”的操作。<br />
    	3,删除主帖,就会删除所有的跟帖(回复)。<br />
    </div>
    
    </body>
    </html>
    

      

     

  • 相关阅读:
    虚拟机VMware配置centos7集群(亲测有效)
    linux虚拟机克隆后,虚拟机ping不通的解决方法
    VC++使用 GDI+等比例缩放图片,并且居中显示
    VS2015 编译OSG Plugins Giflib静态库
    Qt 读写文件操作
    OSG 常用快捷键(全屏、查看帧数、截屏)
    Navicat Premium v15 中文最新破解版(附:激活工具)
    redis 持久化机制及配置
    Redis 五种数据类型
    linux 安装redis
  • 原文地址:https://www.cnblogs.com/fengli9998/p/6600284.html
Copyright © 2011-2022 走看看