[背景] 最近学习Spring MVC,涉及到分页显示的问题,准备自己整理一个分页工具。由于以前使用Strus框架使用 NewPandaKing 的一个PageBean和Page方法,耦合性比较高,于是优化一下。
[优点] 耦合低,使用方便。
[缺点] 由于耦合低,不查数据库,所以每次使用List的sublist方法,效率降低。
代码如下:
分页工具类:PageUtil.java
/** * Java 分页工具类 */ package com.util; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author neuhxy * @version 2015-4-23 15:25:21 * */ public class PageUtil { private int page = 1; // 当前页 public int total = 0; // 总页数 private int size = 10; // 每页10条数据 private int totalRows = 0; // 总数据数 private int pageStartRow = 0;// 每页的起始数 private int pageEndRow = 0; // 每页显示数据的终止数 private boolean hasNextPage = false; // 是否有下一页 private boolean hasPreviousPage = false; // 是否有前一页 private List<?> list; // 分页组件包含的集合 private List<?> show; // 分页中需要显示的List private String action; // 设置跳转URL private String method = "GET"; // 使用POST或者GET请求 @SuppressWarnings("unused") private String code1; // 分页组件的现实代码 @SuppressWarnings("unused") private String code2; // 分页组件的现实代码 private Map<String, Object> map = new HashMap<String, Object>(); // 隐含条件 public int[] sizeArray = { 10, 20, 50, 100, 1000, 10000 }; //默认构造函数 public PageUtil () {} /** * @param list * @param size */ public PageUtil(List<?> list, int size) { this.size = size; this.list = list; totalRows = list.size(); hasPreviousPage = false; if ((totalRows % size) == 0) { total = totalRows / size; } else { total = totalRows / size + 1; } if (page >= total) { hasNextPage = false; } else { hasNextPage = true; } if (totalRows < size) { this.pageStartRow = 0; this.pageEndRow = totalRows; } else { this.pageStartRow = 0; this.pageEndRow = size; } } // 第一种样式 <ul> / <li> 格式 public String getCode1() { StringBuffer sb = new StringBuffer(); sb.append("<form action=\"" + getAction() + "\" method=\"" + getMethod() + "\">"); sb.append("<ul class=\"pagination text-center\">"); // 判断是否有上一页 if (this.isHasPreviousPage()) { sb.append("<li class=\"disabled\"><a href=\"#\">«</a></li>"); } else { sb.append("<li class=\"disabled\"><a href=\"#\">«</a></li>"); } // 中间显示 for (int i = 1; i <= this.getTotal(); i++) { String spanClzz = "<li><a href=\"" + getAction() + "?page=" + i + "\"> " + i + " <span class=\"sr-only\">(current)</span></a></li>"; if (this.page == i) { spanClzz = "<li class=\"active\"><a href=\"#\">" + i + " <span class=\"sr-only\">(current)</span></a></li>"; } sb.append(spanClzz); // 当大于9页数的时候才进行分页显示 if (this.getTotal() - 2 > 7) { if (i == 5) { i = this.getTotal() - 2; sb.append("<li><a href=\"#\"> ... <span class=\"sr-only\">(current)</span></a></li>"); } } } // 判断是否有下一页 if (this.isHasNextPage()) { sb.append("<li><a href=\"#\">»</a></li>"); } else { sb.append("<li class=\"disabled\"><a href=\"#\">»</a></li>"); } sb.append("</ul></form>"); return sb.toString(); } // 第二种分页样式 <a> 带分页现实多少条记录设置 public String getCode2() { StringBuffer sb = new StringBuffer(); String code = "<div class=\"pager clearfix text-center\">"; String scripts = "<script> " + "function subPage(p){" + "document.pageForm.elements['page'].value = p;" + "document.pageForm.submit();" + "} " + " function subPageSize(pageSize){ " + " document.pageForm.submit();" + "}</script>"; setMethod("POST"); code += "<form name=\"pageForm\" action=\"" + getAction() + "\" method=\"" + getMethod() + "\">"; String hidden = "<input type=\"hidden\" name=\"page\" value=\"" + page + "\">"; if (!map.isEmpty()) { for (String key : map.keySet()) { System.out.println("key= " + key + " and value= " + map.get(key)); hidden += "<input type=\"hidden\" name=\"" + key + "\" value=\"" + map.get(key) + "\" />"; } } code += hidden; code += scripts; // 底面样式 首页 上一页 if (this.getPage() != 1) { code += "<a href=\"javascript:subPage(1)\">首页</a> " + "<a href=\"javascript:subPage(" + (this.getPage() - 1) + ")\">上一页</a> "; } // 跳第几页 code += "第<select style=\"width:60px;\" onchange=\"javascript:subPage(this.value)\" class=\"numbox\">"; for (int i = 1; i <= this.getTotal(); i++) { if (i == this.getPage()) { code += "<option value=" + i + " selected='selected'>" + i + "</option>"; } else { code += "<option value=" + i + ">" + i + "</option>"; } } code += "</select>页,共" + this.getTotal() + "页 "; // 每页显示几个记录 code += "每页显示<select style=\"width:60px;\" name=\"size\" onchange=\"javascript:subPageSize(this.value)\" class=\"numbox\">"; for (int j = 0; j < sizeArray.length; j++) { if (sizeArray[j] == this.getSize()) { code += "<option value=" + sizeArray[j] + " selected='selected'>" + sizeArray[j] + "</option>"; } else { code += "<option value=" + sizeArray[j] + ">" + sizeArray[j] + "</option>"; } } code += "</select>条记录"; // 下一页 尾页 if (this.getPage() != this.getTotal()) { code += "<a href=\"javascript:subPage(" + (this.getPage() + 1) + ")\">下一页</a> " + "<a href=\"javascript:subPage(" + this.getTotal() + ")\">尾页</a>"; } code += "</div>"; sb.append(code); sb.append("</form>"); return sb.toString(); } // 判断要不要分页 public boolean isNext() { return list.size() > 5; } public void setHasPreviousPage(boolean hasPreviousPage) { this.hasPreviousPage = hasPreviousPage; } // 获取下一个内容 public List<?> getNextPage() { page = page + 1; disposePage(); return getShow(page); } // 处理分页 private void disposePage() { if (page == 0) { page = 1; } if ((page - 1) > 0) { hasPreviousPage = true; } else { hasPreviousPage = false; } if (page >= total) { hasNextPage = false; } else { hasNextPage = true; } } // 获取上一页内容 public List<?> getPreviousPage() { page = page - 1; if ((page - 1) > 0) { hasPreviousPage = true; } else { hasPreviousPage = false; } if (page >= total) { hasNextPage = false; } else { hasNextPage = true; } return getShow(page); } public List<?> getShow() { return show; } // 获取第 n 页内容 public List<?> getShow(int page) { if (page == 0) { this.setPage(1); page = 1; } else { this.setPage(page); } this.disposePage(); if (page * size < totalRows) {// 判断是否为最后一页 pageEndRow = page * size; pageStartRow = pageEndRow - size; } else { pageEndRow = totalRows; pageStartRow = size * (total - 1); } List<?> show = null; if (!list.isEmpty()) { show = list.subList(pageStartRow, pageEndRow); } return show; } // 获取第一页内容 public List<?> getFistPage() { if (this.isNext()) { return list.subList(0, size); } else { return list; } } //部分get set 方法自动补全即可 }
Spring-MVC Controller部分: UserController.java
@RequestMapping("view_user") public String view_user(PageUtil p, HttpServletRequest request) { //……仅提供部分关键代码 //分页组件用法:首先获取所有List List<User> users = userService.getUserList(); PageUtil pu = new PageUtil(users, p.getSize()); pu.setShow(pu.getShow(p.getPage())); //告诉分页跳转URL, 对应这个方法本身的路径 pu.setAction("../user/view_user"); request.setAttribute("pu", pu); return "admin/view_user"; }
在页面上显示部分:view_user.jsp
<c:if test="${!empty pu.show}"> <c:forEach items="${pu.show}" var="item"> <td>${item.id }</td> <!--显示具体内容--> </c:forEach> </c:if> <!-- 以下两种方式任选其一 --> <!--显示分页代码1 使用Bootstrap 库样式 需要额外引入bootstrap.css --> ${pu.code1} <!--显示分页代码1, 使用默认样式, 功能全 --> ${pu.code2}
参考资料:
[1] http://www.cnblogs.com/wenqiangwu/archive/2013/01/21/page_util.html