[背景] 最近学习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;\" οnchange=\"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\" οnchange=\"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