4、OA分页设计
来源:互联网 发布:哪个运营商的4g网络好 编辑:程序博客网 时间:2024/05/13 23:47
分页设计思路:
JSP中与分页相关的信息
l 要显示本页的数据列表
• 使用<s:iterator value=“%{recordList}”>循环显示
l 要显示分页信息,包括:
• 当前页码、总页码数、每页显示多少条、总记录数
• 页码列表,只显示当前页附近的10个页码
•
recordList 本页的数据列表
currentPage 当前页
pageCount 总页数
pageSize 每页显示多少条数据
recordCount 总记录数
beginPageIndex 页码列表的开始索引
endPageIndex 页码列表的结束索引
快速转到功能:使用下拉列表显示所有的页码,选中某页码后就转到相应的页面
使用Hibernate获取分页的数据
l 在Hibernate中获取一段数据的方式是:
• Query.setFirstResult(int)
• Query.setMaxResults(int)
举例:假设共有25条数据,每页显示10条(pageSize=10),则总共3页,获取每页数据的firstResult与maxResult分别为:
• 第1页:first=0,max=10
• 第2页:first=10,max=10
• 第3页:first=20,max=10
l 公式说明:
• 计算firstResult的公式为:(当前页-1) * pageSize
• maxResults就是pageSize的值
总页数及页码列表的开始与结束索引的计算方法
l 计算总页码数pageCount的方式为:
• 方式1:recordCount / pageSize,如果有余数,就再加1页
• 方式2:(recordCount + pageSize - 1) / pageSize
l 计算beginPageIndex与endPageIndex(最多显示当前页附近的10个页码)
• 总页数小于等于10页,则全部显示
• 总页数大于10页
• 默认显示当前页附件近的10个页码(前4个 + 当前页 + 后5个)
• 前面不足4个页码时,就显示前10个页码
• 后面不足5个页码时,就显示后10个页码
一、 基本分页
topicAction/show.jsp
=========分页的信息 ==========
页次:${currentPage}/{pageCount}页
每页显示:${pageSize}条
总记录数:${recordCount}条
<s:iteratorbegin="%{beginPageIndex}" end="%{endPageIndex}"var="num">
${num}
</s:iterator>
转到:
<select id="pn"onchange="gotoPage(this.value)">
<s:iteratorbegin="1" end="%{pageCount}" var="num">
<optionvalue="${num}">${num}</option>
</s:iterator>
</select>
<script>
functiongotoPage( pageNum ){
window.location.href="xxx.action?pageNum=" + pageNum;
}
</script>
TopicAction中
/** 显示单个主题(主帖 +回帖列表) */
public String show()throws Exception{
//准备数据
//Topic
Topic topic=topicService
.getById(model.getId());
ActionContext.getContext()
.put("topic", topic);
PageBean pageBean=replyService
.getPageBean(pageNum,topic);
ActionContext.getContext()
.getValueStack().push(pageBean);
return "show";
}
ReplyServiceImpl中
public PageBean getPageBean(int pageNum, Topic topic){
int pageSize=Configuration.getPageSize();
//查询本页的数据列表
List list=getSession().createQuery(//
"FROM Reply r WHERE r.topic=?
ORDER BY r.postTime")
.setParameter(0, topic)
.setFirstResult((pageNum-1)*pageSize)
.setMaxResults(pageSize)
.list();
// 查询总记录数
Long recordCount=(Long) getSession()
.createQuery(//
"SELECT count(*) FROM
Reply r WHERE r.topic=?")
.setParameter(0, topic)
.uniqueResult();
return new PageBean(pageNum, pageSize,
recordCount.intValue(), list);
}
各种数据列表查询,不同的只是HQL与其中的参数列表,所以把这两个信息作为参数传到公共方法中就可以了,其中HQL
只需要传递“查询数据列表”的就行,要想查询总记录数,直接在这个HQL前面加上“select count(*)”就可以得到查询总数量的HQL语句。所以,设计的方法如下:
public class PageBean {
// 传递的参数或是配置的参数
private int currentPage; //当前页
private int pageSize; //每页显示多少条记录
// 查询数据库
private int recordCount; //总记录数
private List recordList ; //本页的数据列表
//計算
private int pageCount; //总页数
private int beginPageIndex; //页码列表的开始索引(包含)
private int endPageIndex; //页码列表的结束索引(包含)
/**
* 只接受4个必要的属性,会自动的计算出其他3个属性的值
* @param currentPage
* @param pageSize
* @param recordCount
* @param recordList
*/
public PageBean(int currentPage,int pageSize,int recordCount, List recordList){
this.currentPage= currentPage;
this.pageSize= pageSize;
this.recordCount= recordCount;
this.recordList= recordList;
//计算总页数
pageCount=(recordCount+pageSize-1)/pageSize;
// 计算 beginPageIndex与 endPageIndex
// >> 总页码小于等于10页时,全部显示
if(pageCount<10){
beginPageIndex=1;
endPageIndex=pageCount;
}
// >> 总页码大于10页时,就只显示当前页附近的共10个页码
else{
// 默认显示前4页 +当前页 + 后5页
beginPageIndex=currentPage-4;
endPageIndex=currentPage+5;
// 如果前面不足4个页码时,则显示前10页
if(beginPageIndex<1){
beginPageIndex=1;
endPageIndex=10;
}
// 如果后面不足5个页码时,则显示后10页
else if(endPageIndex>pageCount){
endPageIndex=pageCount;
beginPageIndex=endPageIndex-9;
}
}
}
ForumAction中:
//准备主题列表的分页信息(使用公共的方法 +过滤与排序)
String hql="FROM Topic t WHERE t.forum=?";
List<Object> parameters=new ArrayList<Object>();
parameters.add(forum);
// >>过滤条件
if(viewType==1){ // 1表示只看精华帖
hql += " AND t.type=? ";
parameters.add(Topic.TYPE_BEST);
}
// >> 排序条件
if(orderBy==0){ //默认排序
hql+="ORDER BY (CASE t.type WHEN 2 THEN 2 ELSE0 END) DESC, t.lastUpdateTime DESC";
}
else if(orderBy ==1){ //1代表只按最后更新时间排序<br>
hql+="ORDER BY t.lastUpdateTime "+(asc?"ASC":"DESC");
}
else if(orderBy ==2){ // 2代表只按主题发表时间排序<br>
hql+="ORDER BY t.postTime "+(asc?"ASC":"DESC");
}
else if(orderBy ==3){ // 3代表只按回复数量排序
hql+="ORDER BY t.replyCount "+(asc?"ASC":"DESC");
}
PageBean pageBean=topicService.getPageBean(pageNum, hql, parameters.toArray());
ActionContext.getContext().getValueStack().push(pageBean);
-----------------------------------------------------------------------------------------------------------------------------------------------------
BaseDaoImpl中:
public PageBean getPageBean(int pageNum, String queryListSQL,Object[] parameters) {
int pageSize=Configuration.getPageSize();
//查询本页的数据列表
Query listQuery=getSession().createQuery(queryListSQL);
if(parameters!=null && parameters.length>0){
for(int i=0;i<parameters.length;i++){
listQuery.setParameter(i, parameters[i]);
}
}
listQuery.setFirstResult((pageNum-1)*pageSize);
listQuery.setMaxResults(pageSize);
List list=listQuery.list();
// 查询总记录数
Query countQuery=getSession().createQuery("SELECT count(*) "+queryListSQL);
if(parameters!=null && parameters.length>0){
for(int i=0;i<parameters.length;i++){
countQuery.setParameter(i, parameters[i]);
}
}
Long recordCount=(Long) countQuery.uniqueResult();
return new PageBean(pageNum, pageSize, recordCount.intValue(), list);
}
===========================================================================================
三、优化
如果有一个辅助生成HQL的工具类HqlHelper(后面页有详细说明),他的作用是持有HQL与参数列表。则这个获取分页信息的公共方法可以设计为:
其中:
HqlHelper.getQueryListHql() 获取生成的查询数据列表的HQL
HqlHelper.getQueryCountHql() 获取生成的查询总数量的HQL(没有OrderBy子句)
HqlHelper.getParameters() 获取参数列表
l 我们所用的查询数据列表的HQL一般的格式如下:
“FROM 实体 WHERE条件1 AND 条件2 AND ... AND 条件n ORDER BY 属性1, 属性2, ..., 属性n”
l 说明:
• From子句必须要有
• Where子句是可选的
• OrderBy子句是可选的
l 说明2:
• Where子句中的多个条件之间是AND的关系,因为使用的场景都是数据列表的过滤,例如用户列表可以按姓名、性别、生日范围等条件过滤,如果指定了多个条件,这多个条件之间都是AND的关系。
• Where子句中的表达式中可能0或多个参数:
• 没有参数的例子:t.forum IS NULL
• 1个参数的例子:t.id=?
• 2个参数的例子:t.id BETWEEN ? AND ?
•
HqlHelper的设计:
public class HqlHelper {
private String fromClause;
private String whereClause="";
private String orderByClause="";
private List<Object> parameters=new ArrayList<Object>();
/**
* 生成From字句,默认别名为"o"
* @param clazz
*/
public HqlHelper(Class clazz){
this.fromClause="FROM "+ clazz.getSimpleName()+" o";
}
/**
* 生成From字句,默认别名为"o"
* @param clazz
*/
public HqlHelper(Class clazz,String alias){
this.fromClause="FROM "+ clazz.getSimpleName()+" "+alias;
}
/**
* 拼接where字句
* @param condition
* @param params
* @return
*/
public HqlHelper addCondition(String condition,Object...params){
//拼接
if(whereClause.length()==0){
whereClause=" WHERE "+ condition;
}else{
whereClause+=" AND "+ condition;
}
// 保存参数
if(params!=null && params.length>0){
for(Object obj:params){
parameters.add(obj);
}
}
return this;
}
/**
* 如果第1个参数为true,则拼接Where子句
*
* @param append
* @param condition
* @param params
* @return
*/
public HqlHelper addCondition(boolean append,String condition,Object...params){
if(append){
addCondition(condition, params);
}
return this;
}
/**
* 拼接order by字句
* @param propertyName
* @param isAsc
* @return
*/
public HqlHelper addOrder(StringpropertyName,boolean isAsc){
if(orderByClause.length()==0){
orderByClause=" ORDER BY "+propertyName+(isAsc?" ASC":" DESC");
}else{
orderByClause+=", "+propertyName+(isAsc?" ASC":" DESC");
}
return this;
}
/**
* 拼接order by字句
* @param propertyName
* @param isAsc
* @return
*/
public HqlHelper addOrder(boolean append,String propertyName,boolean isAsc){
if(append){
addOrder(propertyName, isAsc);
}
return this;
}
/**
* 获取生成的查询数据列表的HQL语句
* @return
*/
public String getQueryListHql(){
return fromClause+ whereClause+ orderByClause;
}
/**
* 获取生成的查询数据列表的HQL语句
* @return
*/
public String getQueryCountHql(){
return "SELECT count(*) "+fromClause+ whereClause;
}
/**
* 获取参数列表,与HQL过滤条件中的'?'一一对应
* @return
*/
public List<Object> getParameters(){
return parameters;
}
public HqlHelper buildPageBeanForStruts2(int pageNum, BaseDao<?> service){
System.out.println("===>HqlHelper.buildPageBeanForStruts2()");
PageBean pageBean = service.getPageBean(pageNum,this);
ActionContext.getContext().getValueStack().push(pageBean);
return this;
}
}
在ForumAction中“:
//========================================(最终版)==========================================
// 最终版:
// 构建查询条件
new HqlHelper(Topic.class,"t")//
.addCondition("t.forum=?", forum)//
.addCondition(viewType==1,"t.type=?", Topic.TYPE_BEST)// 1表示只看精华帖
.addOrder(orderBy==1,"t.lastUpdateTime", asc)// 1 代表只按最后更新时间排序
.addOrder(orderBy==2,"t.postTime", asc)// 2 代表只按主题发表时间排序
.addOrder(orderBy==3,"t.replyCount", asc)// 3 代表只按回复数量排序
.addOrder(orderBy==0,"(CASE t.type WHEN 2 THEN 2 ELSE 0END)",false)//
.addOrder(orderBy==0,"t.lastUpdateTime",false)// 0 代表默认排序(所有置顶帖在前面,并按最后更新时间降序排列)
.buildPageBeanForStruts2(pageNum, replyService);
return "show";
- 4、OA分页设计
- OA项目之分页
- 【OA】——封装分页
- OA流程表设计
- OA权限系统设计
- oa权限设计
- OA需求设计
- Web系统OA界面设计和开发,OA设计开发指南,OA界面设计,OA系统开发
- OA架构设计之启示
- OA架构设计之启示
- OA系统的设计文档
- 一份OA的数据库设计
- OA系统的设计原则
- OA系统权限模型设计
- OA系统通知管理设计
- 通达OA工作流-表单设计
- 通达OA工作流-流程设计
- OA-分页查询(抽象最终版)一
- 关于 sudo 在aix 上的 安装 配置
- 在mini2440上移植minicom
- C语言"#","#@"和"##"在宏定义中的使用技巧
- MyEclipse中如何去掉JS或JSP语法错误提示
- Linux下缓冲区溢出攻击的原理及对策
- 4、OA分页设计
- execl 日历控件使用
- RMAN backup
- Java判断字符是否是汉字
- sqlserver 根据一个泛型id查询数据,批量删除数据
- android状态机
- Linux系统启动详解
- 大学生如何确定职业目标的方法
- Gzip压缩封装