分页,这项功能在每个页面可能都会体现到,如果每个页面都有,那好我们就把分页这部分抽象,看下面代码
页面:
- <%@ page language=“java” import=“java.util.*” pageEncoding=“utf-8”%>
- <%@ taglib prefix=“s” uri=“/struts-tags” %>
- <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>
- <s:iterator begin=“%{beginPageIndex}” end=“%{endPageIndex}” var=“num”>
- <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 οnchange=“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 = “forum_show.action?id=${id}&pageNum=” + pageNum;
- $(document.forms[0]).append(“<input type=’hidden’ name=’pageNum’ value='” + pageNum +“‘>”);
- document.forms[0].submit();
- }
- </script>
这样我们在有分页的页面中只需写这样的一段代码就搞定了。
- <!–分页信息–>
- <%@ include file=“/WEB-INF/jsp/public/pageView.jspf” %>
PageBean代码:
- package cn.itcast.oa.domain;
- import java.util.List;
- /**
- * 分页功能中的一页的信息
- *
- * @author 志鹏
- *
- */
- 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 {
- // 当前页附近的共10个页码(前4个 + 当前页 + 后5个)
- beginPageIndex = currentPage – 4;
- endPageIndex = currentPage + 5;
- // 当前面的页码不足4个时,则显示前10个页码
- if (beginPageIndex < 1) {
- beginPageIndex = 1;
- endPageIndex = 10;
- }
- // 当后面的页码不足5个时,则显示后10个页码
- if (endPageIndex > pageCount) {
- endPageIndex = pageCount;
- beginPageIndex = pageCount – 10 + 1;
- }
- }
- }
- }
上面代码中的一些get set(记得写)方法我删除了,看到上面这个类中的方法和业务逻辑其实并不难,但是如果重复性的工作多了,这些东西也是够折磨你的
QueryHelper工具类:
- <span style=“font-size:18px;”>package cn.itcast.oa.util;
- import java.util.ArrayList;
- import java.util.List;
- import cn.itcast.oa.base.DaoSupport;
- import cn.itcast.oa.domain.PageBean;
- import com.opensymphony.xwork2.ActionContext;
- /**
- * 用于辅助拼接HQL语句
- *
- * @author 志鹏
- *
- */
- public class QueryHelper {
- private String fromClause; // FROM子句
- private String whereClause = “”; // Where子句
- private String orderByClause = “”; // OrderBy子句
- private List<Object> parameters = new ArrayList<Object>(); // 参数列表
- /**
- * 生成From子句
- *
- * @param clazz
- * @param alias
- * 别名
- */
- public QueryHelper(Class clazz, String alias) {
- fromClause = “FROM “ + clazz.getSimpleName() + ” “ + alias;
- }
- /**
- * 拼接Where子句
- *
- * @param condition
- * @param params
- */
- public QueryHelper addCondition(String condition, Object… params) {
- // 拼接
- if (whereClause.length() == 0) {
- whereClause = ” WHERE “ + condition;
- } else {
- whereClause += ” AND “ + condition;
- }
- // 参数
- if (params != null) {
- for (Object p : params) {
- parameters.add(p);
- }
- }
- return this;
- }
- /**
- * 如果第一个参数为true,则拼接Where子句
- *
- * @param append
- * @param condition
- * @param params
- */
- public QueryHelper addCondition(boolean append, String condition, Object… params) {
- if (append) {
- addCondition(condition, params);
- }
- return this;
- }
- /**
- * 拼接OrderBy子句
- *
- * @param propertyName
- * 参与排序的属性名
- * @param asc
- * true表示升序,false表示降序
- */
- public QueryHelper addOrderProperty(String propertyName, boolean asc) {
- if (orderByClause.length() == 0) {
- orderByClause = ” ORDER BY “ + propertyName + (asc ? ” ASC” : ” DESC”);
- } else {
- orderByClause += “, “ + propertyName + (asc ? ” ASC” : ” DESC”);
- }
- return this;
- }
- /**
- * 如果第一个参数为true,则拼接OrderBy子句
- *
- * @param append
- * @param propertyName
- * @param asc
- */
- public QueryHelper addOrderProperty(boolean append, String propertyName, boolean asc) {
- if (append) {
- addOrderProperty(propertyName, asc);
- }
- return this;
- }
- /**
- * 获取生成的用于查询数据列表的HQL语句
- *
- * @return
- */
- public String getListQueryHql() {
- return fromClause + whereClause + orderByClause;
- }
- /**
- * 获取生成的用于查询总记录数的HQL语句
- *
- * @return
- */
- public String getCountQueryHql() {
- return “SELECT COUNT(*) “ + fromClause + whereClause;
- }
- /**
- * 获取HQL中的参数值列表
- *
- * @return
- */
- public List<Object> getParameters() {
- return parameters;
- }
- /**
- * 查询分页信息,并放到值栈栈顶
- *
- * @param service
- * @param pageNum
- * @param pageSize
- */
- public void preparePageBean(DaoSupport<?> service, int pageNum, int pageSize) {
- PageBean pageBean = service.getPageBean(pageNum, pageSize, this);
- ActionContext.getContext().getValueStack().push(pageBean);
- }
- }
- </span>
简单介绍,如果我们的参数过多,我们可以根据循环来进行赋值,这样都避免了赋值繁杂,和一些空格的错误了。
OA系统的抽象不仅仅这些,比如一些公共的GetById(),FindAll()等等这样公共的底层方法,我们都抽象到了一个叫做DaoSupportImpl这样的实现类中,那么我们的分页功能也有这样的公共方法我们依旧抽象出来放在DaoSupportImpl实现类中,看下面代码:
PageBean方法:
- <span style=“font-size:18px;”>// 公共的查询分页信息的方法(最终版)
- public PageBean getPageBean(int pageNum, int pageSize, QueryHelper queryHelper) {
- // 参数列表
- List<Object> parameters = queryHelper.getParameters();
- // 查询本页的数据列表
- Query listQuery = getSession().createQuery(queryHelper.getListQueryHql()); // 创建查询对象
- if (parameters != null) { // 设置参数
- for (int i = 0; i < parameters.size(); i++) {
- listQuery.setParameter(i, parameters.get(i));
- }
- }
- listQuery.setFirstResult((pageNum – 1) * pageSize);
- listQuery.setMaxResults(pageSize);
- List list = listQuery.list(); // 执行查询
- // 查询总记录数量
- Query countQuery = getSession().createQuery(queryHelper.getCountQueryHql());
- if (parameters != null) { // 设置参数
- for (int i = 0; i < parameters.size(); i++) {
- countQuery.setParameter(i, parameters.get(i));
- }
- }
- Long count = (Long) countQuery.uniqueResult(); // 执行查询
- return new PageBean(pageNum, pageSize, count.intValue(), list);
- }
- </span>
注一
:
大家也许会奇怪,那怎么进行具体的查询呢,比如我是板块查询,没有看到真正的hql语句和表的查询呀,当然我们一些特殊的我们会进行重写呀,比如下面这段代码,就是重写的过程:
- <span style=“font-size:18px;”>public PageBean getPageBeanByForum(int pageNum, int pageSize, Forum forum) {
- // 查询本页的数据列表
- List list = getSession().createQuery(//
- “FROM Topic t WHERE t.forum=? ORDER BY (CASE t.type WHEN 2 THEN 2 ELSE 0 END) DESC, t.lastUpdateTime DESC”)//
- .setParameter(0, forum)//
- .setFirstResult((pageNum – 1) * pageSize)//
- .setMaxResults(pageSize)//
- .list();
- // 查询总记录数量
- Long count = (Long) getSession().createQuery(//
- “SELECT COUNT(*) FROM Topic t WHERE t.forum=?”)//
- .setParameter(0, forum)//
- .uniqueResult();
- return new PageBean(pageNum, pageSize, count.intValue(), list);
- }</span>
注二:
关于这段内容都这些了,让我很疑惑的是,在action中的hql语句,是不是会让我们的架构设计不够明确呢,hql语句应该放在底层,而不是Action呀,看下面代码:
Action代码:
- <span style=“font-size:18px;”>// 准备分页信息 ,最终版
- new QueryHelper(Topic.class, “t”)//
- // 过滤条件
- .addCondition(“t.forum=?”, forum)//
- .addCondition((viewType == 1), “t.type=?”, Topic.TYPE_BEST) // 1 表示只看精华帖
- // 排序条件
- .addOrderProperty((orderBy == 1), “t.lastUpdateTime”, asc) // 1 表示只按最后更新时间排序
- .addOrderProperty((orderBy == 2), “t.postTime”, asc) // 2 表示只按主题发表时间排序
- .addOrderProperty((orderBy == 3), “t.replyCount”, asc) // 3 表示只按回复数量排序
- .addOrderProperty((orderBy == 0), “(CASE t.type WHEN 2 THEN 2 ELSE 0 END)”, false)//
- .addOrderProperty((orderBy == 0), “t.lastUpdateTime”, false) // 0 表示默认排序(所有置顶帖在前面,并按最后更新时间降序排列)
- .preparePageBean(topicService, pageNum, pageSize);
- </span>
注一和注二可以替换为:
public String list() throws Exception {
PageBean pageBean = new QueryHelper(User.class, “u”)//
.preparePageBean(userService, pageNum, pageSize);
//结果放到栈顶
ActionContext.getContext().getValueStack().push(pageBean);
return “list”;
}
在jsp中的应用:
<s:form action=”userAction_list”></s:form> //查下一页时,先从后台查询数据
<%@ include file=”/WEB-INF/jsp/public/pageView.jspf” %>//此页面便是存放数据分页的jsp页面,即最上面页面代码
今天的文章java 分页分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/64551.html