【Java EE 学习 57】【酒店会员管理系统之分页模板书写】
分页一直是一个比较麻烦的问题,特别是在我做的这个系统中更是有大量的分页,为了应对该问题,特地写了一个模板以方便代码重用,该模板包括后台分页的模板、前端显示的模板两部分。
一、分页分析
分页需要三种类型的参数:
1.系统启动之后就能够确定的参数,比如每页显示多少条数据pageSize,分页长度:elementLength
2.浏览器动态请求的参数这种情况分为两种:带有请求的页码(requestPage)和不带有请求的页码。
由于后台的分页代码是重用的,所以第一次请求的时候就需要带上请求的页码,如果不带上请求的页码默认是1,这需要后台代码进行判断。
3.服务器响应的数据,比如首页码(startIndex)、尾页码(endIndex)、总共的页码(totalPages)、当前的页码(currentPage=requestPage),当然还有响应的数据。
二、前端页面
发起分页请求的可能是一个超链接触发,也有可能是一个查询按钮触发,请求的方法都是同一个方法。
1.超链接触发
2.查询按钮触发
对于超链接触发的,可以直接访问action,但是查询按钮触发的却需要做一些动作才行。
(1)表单设置隐藏域,设置默认请求页码或者大多部分提供给js进行更改请求页码并提交给Action。
<s:hidden name="requestPage" value="1"></s:hidden>
(2)不能直接提交,需要先通过js进行设置:
/*
*多条件查询和分页页面使用的js
*/
$().ready(function(){
$("#pageSplit a").each(function(){
$(this).unbind("click");
$(this).bind("click",function(){
var requestPage=$(this).attr("href").split("requestPage=")[1];
$("input[name='requestPage']").val(requestPage);
$("form").submit();
return false;
});
});
$("#query").unbind("click");
$("#query").bind("click",function(){
$("form").submit();
});
});
#pageSplit a是前端的jsp(struts2)分页模板,后边介绍。
3.前端显示的jsp分页模板(struts2)
<div id="pageSplit">
<s:a>首页
<s:param name="requestPage" value="1"></s:param>
</s:a>
<s:a>上一页
<s:param name="requestPage" value="#requestPage-1>0?#requestPage-1:1"></s:param>
</s:a>
<s:iterator var="page" begin="%{#startIndex}" end="%{#endIndex}">
<s:if test="#page==#requestPage">
<s:a cssStyle="background-color: #91C0E3;">
<s:param name="requestPage" value="#page"></s:param>
<s:property value="#page"/>
</s:a>
</s:if>
<s:else>
<s:a>
<s:param name="requestPage" value="#page"></s:param>
<s:property value="#page"/>
</s:a>
</s:else>
</s:iterator>
<s:if test="%{#totalPages>#endIndex}">
......
<s:a>
<s:param name="requestPage" value="#endIndex+1"></s:param>
共有
<s:property value="%{#totalPages}"/>页</s:a>
</s:if>
<s:else>
<s:a>
<s:param name="requestPage" value="%{#totalPages}"></s:param>
共有
<s:property value="%{#totalPages}"/>页</s:a>
</s:else>
<s:a>
下一页
<s:param name="requestPage" value="#requestPage+1>#totalPages?#totalPages:#requestPage+1"></s:param>
</s:a>
<s:a>
尾页
<s:param name="requestPage" value="#totalPages"></s:param>
</s:a>
</div>
结合的css样式模板
#pageSplit{
margin-top:7px;
margin-bottom:7px;
font-size: 14px;
text-align: center;
}
#pageSplit a{
display: inline-block;
background-color:#CEE5EA;
border :1px solid ;
padding-top: 3px;
padding-bottom: 3px;
padding-left: 7px;
padding-right:7px;
color: #004779;
text-decoration: none;
}
#pageSplit a:HOVER {
background-color: #ADD8E5;
}
#query{
font-size:12px;
width: 50px;
height: 24px;
text-align: center;
margin: 0px;
}
二、后台分页逻辑实现
1.通过监听器确定初始化的两个参数:pageSize和elementLength
首先将参数放到配置文件中:init.properties
#every pages show 12 datas
pageSize=10
#show the choose length prePage,1,2,3,4,5,6,7,8 nextPage
splitPageLength=5
监听器获取
InputStream is=MyServletContextListener.class.getClassLoader().getResourceAsStream("init.properties");
Properties initProperties=new Properties();
initProperties.load(is);
PageSplitConfig.splitPageLength=Integer.parseInt(initProperties.getProperty("splitPageLength"));
PageSplitConfig.pageSize=Integer.parseInt(initProperties.getProperty("pageSize"));
这样就将两个参数封装到了PageSplitConfig类中:
public class PageSplitConfig {
//首先是每页显示多少条数据
public static Integer pageSize;
//分页的长度
public static Integer splitPageLength;
}
2.Action中进行分页的逻辑控制:
以showAllCards方法为例:
public String showAllCards(){
//预配置代码
/*Collection<Card>list=cardService.getAllCards();
ActionContext.getContext().put("cardlist", list);*/
Collection<CredentialType> credentialTypes=credentialTypeService.getAllCredentialTypes();
List<String> allCredentialTypes=new ArrayList<String>();
for(CredentialType temp:credentialTypes){
allCredentialTypes.add(temp.getCredentialTypeName());
}
ActionContext.getContext().put("credentialTypes", allCredentialTypes);
//预配置代码结束 //获取请求参数开始
HttpServletRequest request=ServletActionContext.getRequest();
String cardId=request.getParameter("cardId");
if(cardId==null||"".equals(cardId)){
ActionContext.getContext().put("cardId", "");
}else{
ActionContext.getContext().put("cardId", cardId);
}
String userName=request.getParameter("userName");
if(userName==null||"".equals(userName)){
ActionContext.getContext().put("userName", "");
}else{
ActionContext.getContext().put("userName",userName);
}
String typeofcredential=request.getParameter("typeofcredential");
if(typeofcredential==null||"".equals(typeofcredential)||"''".equals(typeofcredential)){
ActionContext.getContext().put("typeofcredential", "");
}else{
ActionContext.getContext().put("typeofcredential", typeofcredential);
}
String sex=request.getParameter("sex");
if(sex==null||"".equals(sex)||"不限".equals(sex)){
ActionContext.getContext().put("sex", "不限");
}else{
ActionContext.getContext().put("sex", sex);
}
String integral=request.getParameter("integral");
if(integral==null||"".equals(integral)){
ActionContext.getContext().put("integral", "");
}else{
ActionContext.getContext().put("integral", integral);
}
//获取请求参数结束 //计算分页参数开始
String requestPage=request.getParameter("requestPage");
if(requestPage==null||"".equals(requestPage.trim())){
requestPage="1";
}
System.out.println("requestPage:"+requestPage);
Collection<Card>cards=cardService.getCardsByMN(Integer.parseInt(requestPage),cardId,userName,
typeofcredential,sex,integral);
int totalLines=this.cardService.getTotalLines(Integer.parseInt(requestPage),cardId,userName,
typeofcredential,sex,integral);
System.out.println("totalLines:"+totalLines);
PageSplitData.requestPage=Integer.parseInt(requestPage);
PageSplitData.calculate(totalLines);
//计算分页参数结束 System.out.println("startIndex:"+PageSplitData.startIndex);
System.out.println("endIndex:"+PageSplitData.endIndex);
System.out.println("totalPages:"+PageSplitData.totalPages);
System.out.println("查询到的会员数量:"+cards.size());
ActionContext.getContext().put("startIndex",PageSplitData.startIndex);
ActionContext.getContext().put("endIndex", PageSplitData.endIndex);
ActionContext.getContext().put("requestPage",PageSplitData.requestPage);
ActionContext.getContext().put("totalPages",PageSplitData.totalPages);
ActionContext.getContext().put("employees", cards);
ActionContext.getContext().put("cardlist", cards);
return listAction;
}
首先需要调用Service方法获取数据和数据总量
Collection<Card>cards=cardService.getCardsByMN(Integer.parseInt(requestPage),cardId,userName,
typeofcredential,sex,integral);
int totalLines=this.cardService.getTotalLines(Integer.parseInt(requestPage),cardId,userName,
typeofcredential,sex,integral);
(1)获取指定分页数据的方法:
public Collection<Card> getCardsByMN(int requestPage, String cardId,
String userName, String typeofcredential, String sex,
String integral) {
int m=(requestPage-1)*PageSplitConfig.pageSize;
int n=PageSplitConfig.pageSize;
String sql="from Card where 1=1 ";
if(cardId!=null&&!"".equals(cardId.trim())){
sql=sql+" and cardId='"+cardId.trim()+"'";
}
if(userName!=null&&!"".equals(userName.trim())){
sql=sql+" and userName='"+userName.trim()+"'";
}
if(typeofcredential!=null&&!"".equals(typeofcredential.trim())&&!"''".equals(typeofcredential.trim())){
sql=sql+" and credentialType.credentialTypeName='"+typeofcredential.trim()+"'";
}
if(sex!=null&&!"".equals(sex.trim())&&!"不限".equals(sex.trim())){
sql=sql+" and sex='"+sex+"'";
}
if(integral!=null&&!"".equals(integral.trim())){
sql=sql+" and integral='"+integral.trim()+"'";
}
return this.cardDao.getAllCards(sql,m,n);
}
该方法会调用DAO方法:
public Collection<Card> getAllCards(String sql, int m, int n) {
Query query=this.hibernateTemplate.getSessionFactory().openSession().createQuery(sql);
query.setFirstResult(m);
query.setMaxResults(n);
return query.list();
}
(2)获取所有数据总量的方法:
public int getTotalLines(int requestPage, String cardId, String userName,
String typeofcredential, String sex, String integral) {
String sql="from Card where 1=1 ";
if(cardId!=null&&!"".equals(cardId.trim())){
sql=sql+" and cardId='"+cardId.trim()+"'";
}
if(userName!=null&&!"".equals(userName.trim())){
sql=sql+" and userName='"+userName.trim()+"'";
}
if(typeofcredential!=null&&!"''".equals(typeofcredential.trim())&&!"".equals(typeofcredential.trim())){
sql=sql+" and credentialType.credentialTypeName='"+typeofcredential.trim()+"'";
}
if(sex!=null&&!"".equals(sex.trim())&&!"不限".equals(sex.trim())){
sql=sql+" and sex='"+sex.trim()+"'";
}
if(integral!=null&&!"".equals(integral.trim())){
sql=sql+" and integral='"+integral.trim()+"'";
}
return this.cardDao.getAllCards(sql).size();
}
调用DAO方法实现:
public Collection<Card> getAllCards(String sql) {
return this.hibernateTemplate.getSessionFactory().openSession().createQuery(sql).list();
}
(3)最重要的分页逻辑的实现在SplitPageData类中:
public class PageSplitData {
//该条数据应该在调用响应方法之前赋值
public static Integer requestPage; //请求之后应该强调显示的页码,即响应之后的当前页或者响应时的响应页码。
public static Integer startIndex; //起始页码
public static Integer endIndex; //最后页码
public static Integer totalPages; //一共有多少页 /**
*
* @param total
*/
public static void calculate(int totalLines){
//每页显示多少条数据
int pageSize=PageSplitConfig.pageSize;
//分页长度
int splitPageLength=PageSplitConfig.splitPageLength;
//已经得到了数据一共有多少条:totalLines 和 请求页 requestPage //得到总页数
totalPages=totalLines/pageSize+(totalLines%pageSize==0?0:1); //计算startIndex和endIndex的关键原则就是endIndex-startIndex的结果是splitPageLength-1
if(splitPageLength%2==0){//分页长度是偶数,为了让当前页在中间,采用前多后少的分页方法
//这种情况下splitPageLength/2+splitPageLength/2==splitPageLength
startIndex=requestPage-(splitPageLength/2+1);//正常情况(针对大数据)
endIndex=requestPage+(splitPageLength/2);//特殊情况(针对大数据)
}else{//分页长度是奇数
//这种情况下splitPageLength/2+splitPageLength/2=splitPageLength-1,符合之前说的原则
startIndex=requestPage-(splitPageLength/2);//这样就正好了
endIndex=requestPage+(splitPageLength/2);//正好
}
if(startIndex<=0){
startIndex=1;
if((startIndex+splitPageLength-1)>totalPages){
endIndex=totalPages;
}else{
endIndex=startIndex+splitPageLength-1;
}
}else{//正常情况
if(endIndex>totalPages){
endIndex=totalPages;
if((endIndex-(splitPageLength-1))<=0){
startIndex=1;
}else{
startIndex=endIndex-(splitPageLength-1);
}
}else{
//正常情况,不做处理
}
}
//需要传递的几个参数都计算完毕
} public static Integer getRequestPage() {
return requestPage;
} public static Integer getStartIndex() {
return startIndex;
} public static Integer getEndIndex() {
return endIndex;
} public static Integer getTotalPages() {
return totalPages;
}
}
三、总结
该分页模板需要的参数通过三种途径传到PageSplitData类中
1.监听器传递pageSize和elementLength两个参数
2.通过set方法设置请求页requestPage
3.直接传递totalLines
计算结果包括
1.首页码:startIndex
2.尾页码:endIndex
3.总页数:totalPages
#pageSplit a
【Java EE 学习 57】【酒店会员管理系统之分页模板书写】的更多相关文章
- 【Java EE 学习 55】【酒店会员管理系统项目总结】
本酒店会员管理系统使用了SSH框架和传值播客提供的协同OA静态页面. 项目地址:https://github.com/kdyzm/HotelMembersManagement 一.需求分析 酒店会员管 ...
- 【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】
一.动态SQL 什么是动态SQL,就是在不同的条件下,sql语句不相同的意思,曾经在“酒店会员管理系统”中写过大量的多条件查询,那是在SSH的环境中,所以只能在代码中进行判断,以下是其中一个多条件查询 ...
- Java EE 学习(8):IDEA + maven + spring 搭建 web(4)- 用户管理
转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) ava E ...
- Java EE学习——Quartz的Cron表达式
经历过低谷后,还是要好好学习,越失落会越来越落后. 今天写一下Cron表达式的用法,虽然是之前自己写的,也过了挺长一段时间,这次就拿出来作为回顾吧. Cron表达式是Quartz的精髓(个人觉得),比 ...
- Java EE 学习(9):IDEA + maven + spring 搭建 web(5)- 博客文章管理
转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) . 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) Jav ...
- Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库
参考: https://my.oschina.net/gaussik/blog/513444 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 ...
- Java EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring
参考:https://my.oschina.net/gaussik/blog/513353 注:此文承接上一文:Java EE 学习(5):IDEA + maven + spring 搭建 web(1 ...
- Java EE 学习(5):IDEA + maven + spring 搭建 web(1)
参考:http://www.cnblogs.com/lonelyxmas/p/5397422.html http://www.ctolib.com/docs-IntelliJ-IDEA-c--1590 ...
- Java EE 学习(4):IDEA + maven 搭建 web(2)
参考:http://www.bubuko.com/infodetail-1855067.html 现使用 Maven 创建项目:本节接Java EE 学习(3):IDEA + maven 搭建 web ...
随机推荐
- linux tomcat 启动
在tomcat bin目录下启动时报权限不够 在bin目录下输入:chmod u+x *.sh 可解决 查看tomcat 是否关闭 ps -ef|grep java 例如显示如下 说明还没关闭root ...
- Salesforce ADM201备考心得
Salesforce拥有很多针对不同角色的认证考试.ADM201是面对初级管理员的认证. 考试形式是单选题和多选题(如果是多选题,题干上会提示你要多选),两个小时时间,60道题目.内容涉及管理Sale ...
- [Asp.net]常见数据导入Excel,Excel数据导入数据库解决方案,总有一款适合你!
引言 项目中常用到将数据导入Excel,将Excel中的数据导入数据库的功能,曾经也查找过相关的内容,将曾经用过的方案总结一下. 方案一 NPOI NPOI 是 POI 项目的 .NET 版本.POI ...
- Genymotion安装及遇到的问题
https://www.genymotion.com/ 首先注册,不注册看不到下载按钮. 注册登陆后下载安装包(一定要记住用户名和密码,因为安装后登陆要用) 一路下一步. 选择虚拟设备 genymot ...
- 每天写点shell——read的用法
1.read基本读取 #!/bin/bash #testing the read command echo -n "Enter you name:" #echo -n 让用户直接在 ...
- Excel——使用OFFSET、MATCH、COUNTA实现二级菜单
如图所示,接下来提供两种办法实现: 1.将A.B.C.D定义为名称NAME. 2.设置一级菜单单元格数据有效性为NAME. 3.设置二级菜单格数据有效为: =OFFSET($A$1,MATCH($A6 ...
- jaee开发起步:tomcat服务器的配置
1.将下载下来的apache-tomcat-6.0.13.zip解压到任意文件夹. (打开tomcat官网,选择下载tomcat6.x.zip版本的tomcat不需要安装,直接解压并配置一下环境变量就 ...
- A()方法
A方法用于在内部实例化控制器,调用格式:A('[项目://][分组/]模块','控制器层名称')最简单的用法: $User = A('User'); 复制代码 表示实例化当前项目的UserActi ...
- VB常用字符串操作函数
1. ASC(X),Chr(X):转换字符字符码 [格式]: P=Asc(X) 返回字符串X的第一个字符的字符码 P=Chr(X) 返回字符码等于X的字符 [范例]: (1)P=Chr(65) ‘ 输 ...
- Netty里的设计模式
最近在撸 Netty 源码,发现了一些模式,顺手做个笔记. 分析版本是4.0 1. 构造器模式 ServerBootstrap 和 Bootstrap 的构建 2. 责任链设计模式 pipeline ...