[背景] 最近学习Spring MVC,涉及到分页显示的问题,准备自己整理一个分页工具。由于以前使用Strus框架使用 NewPandaKing 的一个PageBean和Page方法,耦合性比较高,于是优化一下。
[优点] 耦合低,使用方便。
[缺点] 由于耦合低,不查数据库,所以每次使用List的sublist方法,效率降低。
代码如下:
分页工具类:PageUtil.java
1 /** 2 * Java 分页工具类 3 */ 4 package com.common.tool.util; 5 6 import java.util.HashMap; 7 import java.util.List; 8 import java.util.Map; 9 10 /** 11 * @author neuhxy 12 * @version 2015-4-23 15:25:21 13 * 14 */ 15 public class PageUtil { 16 17 private int page = 1; // 当前页 18 public int total = 0; // 总页数 19 private int size = 10; // 每页5条数据 20 private int slice = 5; // 切片,当页大于切片时,进行分页处理 21 private int totalRows = 0; // 总数据数 22 private int pageStartRow = 0;// 每页的起始数 23 private int pageEndRow = 0; // 每页显示数据的终止数 24 private boolean hasNextPage = false; // 是否有下一页 25 private boolean hasPreviousPage = false; // 是否有前一页 26 private List<?> list; // 分页组件包含的集合 27 private List<?> show; // 分页中需要显示的List 28 private String action; // 设置跳转URL 29 private String method = "GET"; // 使用POST或者GET请求 30 @SuppressWarnings("unused") 31 private String code1; // 分页组件的现实代码 32 @SuppressWarnings("unused") 33 private String code2; // 分页组件的现实代码 34 private Map<String, Object> map = new HashMap<String, Object>(); // 隐含条件 35 public int[] sizeArray = { 10, 20, 50, 100, 1000, 5000 }; // 设置几种可以显示的条数 36 37 // 默认构造函数 38 public PageUtil() { 39 } 40 41 /** 42 * 分页初始化 43 * 44 * @param list 45 * @param size 46 */ 47 public void init(List<?> initList, int pageSize) { 48 if (null != initList) { 49 50 this.setSize(pageSize); 51 this.setList(initList); 52 53 totalRows = initList.size(); 54 55 hasPreviousPage = false; 56 57 if ((totalRows % this.getSize()) == 0) { 58 total = totalRows / this.getSize(); 59 } else { 60 total = totalRows / this.getSize() + 1; 61 } 62 63 if (page >= total) { hasNextPage = false; } else { hasNextPage = true; } 64 65 if (totalRows < this.getSize()) { 66 this.pageStartRow = 0; 67 this.pageEndRow = totalRows; 68 } else { 69 this.pageStartRow = 0; 70 this.pageEndRow = this.getSize(); 71 } 72 this.setShow(getShow(this.getPage())); 73 } 74 75 } 76 77 // 第一种样式 <ul> / <li> 格式 78 public String getCode1() { 79 80 StringBuffer sb = new StringBuffer(); 81 sb.append("<form style='text-align:center;' action="" + getAction() + "" method="" + getMethod() + "">"); 82 sb.append("<ul class="pagination">"); 83 84 // 判断是否有上一页 85 if (isHasPreviousPage()) { 86 sb.append("<li><a href="" + getAction() + "?page=1">«</a></li>"); 87 sb.append("<li><a href="" + getAction() + "?page=" + (getPage() - 1) + ""><</a></li>"); 88 } else { 89 sb.append("<li class="disabled"><a href="#">«</a></li>"); 90 sb.append("<li class="disabled"><a href="#"><</a></li>"); 91 } 92 93 // 中间显示 94 // 当总页数大于切片时,才显示 ... 分页效果 95 if (getTotal() > getSlice()) { 96 97 // 如果当前页码在 1 - getSlice(),显示右侧 ... 翻页按钮 98 if (getPage() > 0 && getPage() <= getSlice() 99 && getPage() < getTotal() - getSlice()) { 100 for (int i = 1; i <= getSlice(); i++) { 101 String spanClzz = "<li><a href="" + getAction() + "?page=" + i + ""> " + i + " <span class="sr-only">(current)</span></a></li>"; 102 103 if (this.page == i) { 104 spanClzz = "<li class="active"><a href="#">" + i + " <span class="sr-only">(current)</span></a></li>"; 105 } 106 sb.append(spanClzz); 107 // 当总页数大于3 的时候 添加右侧 ... 分页 108 } 109 if (getTotal() > getSlice() +1 ) { 110 String dotClzz = "<li><a href="" + getAction() + "?page=" + (getSlice() +1) + ""> ... <span class="sr-only">(current)</span></a></li>"; 111 sb.append(dotClzz); 112 } 113 114 } 115 // 如果当前页码在6 到 total - 6 页,显示两端的两个 ...翻页按钮 116 if (getPage() > getSlice() && getPage() <= getTotal() - getSlice()) { 117 String dotClzz = "<li><a href="" 118 + getAction() 119 + "?page=" 120 + (getPage() - ((getSlice() + 1) / 2)) 121 + ""> ... <span class="sr-only">(current)</span></a></li>"; 122 sb.append(dotClzz); 123 for (int i = getPage() - ((getSlice() - 1) / 2); i <= getPage() 124 + ((getSlice() - 1) / 2); i++) { 125 String spanClzz = "<li><a href="" 126 + getAction() 127 + "?page=" 128 + i 129 + ""> " 130 + i 131 + " <span class="sr-only">(current)</span></a></li>"; 132 133 if (this.page == i) { 134 spanClzz = "<li class="active"><a href="#">" 135 + i 136 + " <span class="sr-only">(current)</span></a></li>"; 137 } 138 sb.append(spanClzz); 139 // 当总页数大于getSlice() 的时候 添加右侧 ... 分页 140 141 } 142 dotClzz = "<li><a href="" 143 + getAction() 144 + "?page=" 145 + (getPage() + ((getSlice() + 1) / 2)) 146 + ""> ... <span class="sr-only">(current)</span></a></li>"; 147 sb.append(dotClzz); 148 149 } 150 // 如果当前页码在total-getSlice() 到 total 页,左侧显示一个...翻页按钮 151 if (getPage() > 0 && getPage() > getTotal() - getSlice() 152 && getPage() <= getTotal()) { 153 154 String dotClzz = "<li><a href="" 155 + getAction() 156 + "?page=" 157 + (getTotal() - getSlice()) 158 + ""> ... <span class="sr-only">(current)</span></a></li>"; 159 sb.append(dotClzz); 160 int s = getTotal() - getSlice() + 1 > 0 ? getTotal() 161 - getSlice() + 1 : 1; 162 for (int i = s; i <= getTotal(); i++) { 163 String spanClzz = "<li><a href="" 164 + getAction() 165 + "?page=" 166 + i 167 + ""> " 168 + i 169 + " <span class="sr-only">(current)</span></a></li>"; 170 171 if (this.page == i) { 172 spanClzz = "<li class="active"><a href="#">" 173 + i 174 + " <span class="sr-only">(current)</span></a></li>"; 175 } 176 sb.append(spanClzz); 177 } 178 179 } 180 } else { 181 // 否则直接显示,有几页显示几页,不加... 182 for (int i = 1; i <= getTotal(); i++) { 183 String spanClzz = "<li><a href="" + getAction() + "?page=" + i 184 + ""> " + i 185 + " <span class="sr-only">(current)</span></a></li>"; 186 187 if (this.page == i) { 188 spanClzz = "<li class="active"><a href="#">" 189 + i 190 + " <span class="sr-only">(current)</span></a></li>"; 191 } 192 sb.append(spanClzz); 193 // 当总页数大于getSlice() 的时候 添加右侧 ... 分页 194 195 } 196 } 197 198 // 判断是否有下一页 199 if (isHasNextPage()) { 200 sb.append("<li><a href="" + getAction() + "?page=" 201 + (getPage() + 1) + "">></a></li>"); 202 sb.append("<li><a href="" + getAction() + "?page=" + getTotal() 203 + "">»</a></li>"); 204 } else { 205 sb.append("<li class="disabled"><a href="#">></a></li>"); 206 sb.append("<li class="disabled"><a href="#">»</a></li>"); 207 } 208 209 sb.append("</ul></form>"); 210 return sb.toString(); 211 } 212 213 // 第二种分页样式 <a> 带分页现实多少条记录设置 214 public String getCode2() { 215 216 StringBuffer sb = new StringBuffer(); 217 String code = "<div class="pager clearfix text-center">"; 218 String scripts = "<script> " + "function subPage(p){" 219 + "document.pageForm.elements['page'].value = p;" 220 + "document.pageForm.submit();" + "} " 221 + " function subPageSize(pageSize){ " 222 + " document.pageForm.submit();" + "}</script>"; 223 224 setMethod("POST"); 225 code += "<form name="pageForm" action="" + getAction() 226 + "" method="" + getMethod() + "">"; 227 228 String hidden = "<input type="hidden" name="page" value="" + page 229 + "">"; 230 if (!map.isEmpty()) { 231 for (String key : map.keySet()) { 232 System.out.println("key= " + key + " and value= " 233 + map.get(key)); 234 hidden += "<input type="hidden" name="" + key 235 + "" value="" + map.get(key) + "" />"; 236 } 237 } 238 code += hidden; 239 code += scripts; 240 241 // 底面样式 首页 上一页 242 if (getPage() != 1) { 243 code += "<a href="javascript:subPage(1)">首页</a> " 244 + "<a href="javascript:subPage(" + (this.getPage() - 1) 245 + ")">上一页</a> "; 246 } else { 247 code += "<span>首页</span> " + "<span>上一页</span> "; 248 } 249 250 // 跳第几页 251 code += "第<select style="60px;" onchange="javascript:subPage(this.value)" class="numbox">"; 252 for (int i = 1; i <= getTotal(); i++) { 253 if (i == this.getPage()) { 254 code += "<option value=" + i + " selected='selected'>" + i 255 + "</option>"; 256 } else { 257 code += "<option value=" + i + ">" + i + "</option>"; 258 } 259 } 260 code += "</select>页,共" + this.getTotal() + "页"; 261 262 // 每页显示几个记录 263 code += ",每页显示<select style="60px;" name="size" onchange="javascript:subPageSize(this.value)" class="numbox">"; 264 for (int j = 0; j < sizeArray.length; j++) { 265 if (sizeArray[j] == getSize()) { 266 code += "<option value=" + sizeArray[j] 267 + " selected='selected'>" + sizeArray[j] + "</option>"; 268 } else { 269 code += "<option value=" + sizeArray[j] + ">" + sizeArray[j] 270 + "</option>"; 271 } 272 } 273 274 code += "</select>条记录"; 275 276 // 下一页 尾页 277 if (getPage() != getTotal()) { 278 code += "<a href="javascript:subPage(" + (getPage() + 1) 279 + ")">下一页</a> " + "<a href="javascript:subPage(" 280 + getTotal() + ")">尾页</a>"; 281 } else { 282 code += "<span>下一页</span> " + "<span>尾页</span> "; 283 } 284 code += "</div>"; 285 sb.append(code); 286 sb.append("</form>"); 287 return sb.toString(); 288 } 289 290 // 判断要不要分页 291 public boolean isNext() { 292 return list.size() > getSlice(); 293 } 294 295 public void setHasPreviousPage(boolean hasPreviousPage) { 296 this.hasPreviousPage = hasPreviousPage; 297 } 298 299 // 获取下一个内容 300 public List<?> getNextPage() { 301 page = page + 1; 302 disposePage(); 303 return getShow(page); 304 } 305 306 // 处理分页 307 private void disposePage() { 308 if (page == 0) { 309 page = 1; 310 } 311 if ((page - 1) > 0) { 312 hasPreviousPage = true; 313 } else { 314 hasPreviousPage = false; 315 } 316 317 if (page >= total) { 318 hasNextPage = false; 319 } else { 320 hasNextPage = true; 321 } 322 } 323 324 // 获取上一页内容 325 public List<?> getPreviousPage() { 326 page = page - 1; 327 328 if ((page - 1) > 0) { 329 hasPreviousPage = true; 330 } else { 331 hasPreviousPage = false; 332 } 333 if (page >= total) { 334 hasNextPage = false; 335 } else { 336 hasNextPage = true; 337 } 338 return getShow(page); 339 } 340 341 public List<?> getShow() { 342 return show; 343 } 344 345 // 获取第 n 页内容 346 public List<?> getShow(int page) { 347 348 if (page == 0) { 349 this.setPage(1); 350 page = 1; 351 } else { 352 this.setPage(page); 353 } 354 355 this.disposePage(); 356 357 if (page * size < totalRows) {// 判断是否为最后一页 358 pageEndRow = page * size; 359 pageStartRow = pageEndRow - size; 360 } else { 361 pageEndRow = totalRows; 362 pageStartRow = size * (total - 1); 363 } 364 365 List<?> show = null; 366 if (!list.isEmpty()) { 367 show = list.subList(pageStartRow, pageEndRow); 368 } 369 return show; 370 } 371 372 // 获取第一页内容 373 public List<?> getFistPage() { 374 if (this.isNext()) { 375 return list.subList(0, size); 376 } else { 377 return list; 378 } 379 } 380 381 public int getPage() { 382 return page; 383 } 384 385 public void setPage(int page) { 386 this.page = page; 387 } 388 389 public int getTotal() { 390 return total; 391 } 392 393 public void setTotal(int total) { 394 this.total = total; 395 } 396 397 public int getSize() { 398 return size; 399 } 400 401 public void setSize(int size) { 402 this.size = size; 403 } 404 405 public int getTotalRows() { 406 return totalRows; 407 } 408 409 public void setTotalRows(int totalRows) { 410 this.totalRows = totalRows; 411 } 412 413 public int getPageStartRow() { 414 return pageStartRow; 415 } 416 417 public void setPageStartRow(int pageStartRow) { 418 this.pageStartRow = pageStartRow; 419 } 420 421 public int getPageEndRow() { 422 return pageEndRow; 423 } 424 425 public void setPageEndRow(int pageEndRow) { 426 this.pageEndRow = pageEndRow; 427 } 428 429 public boolean isHasNextPage() { 430 return hasNextPage; 431 } 432 433 public void setHasNextPage(boolean hasNextPage) { 434 this.hasNextPage = hasNextPage; 435 } 436 437 public List<?> getList() { 438 return list; 439 } 440 441 public void setList(List<?> list) { 442 this.list = list; 443 } 444 445 public boolean isHasPreviousPage() { 446 return hasPreviousPage; 447 } 448 449 public String getAction() { 450 return action; 451 } 452 453 public void setAction(String action) { 454 this.action = action; 455 } 456 457 public String getMethod() { 458 return method; 459 } 460 461 public void setMethod(String method) { 462 this.method = method; 463 } 464 465 public Map<String, Object> getMap() { 466 return map; 467 } 468 469 public void setMap(Map<String, Object> map) { 470 this.map = map; 471 } 472 473 public void setShow(List<?> show) { 474 this.show = show; 475 } 476 477 public void setCode1(String code1) { 478 this.code1 = code1; 479 } 480 481 public void setCode2(String code2) { 482 this.code2 = code2; 483 } 484 485 public int getSlice() { 486 return slice; 487 } 488 489 public void setSlice(int slice) { 490 this.slice = slice; 491 } 492 493 public int[] getSizeArray() { 494 return sizeArray; 495 } 496 497 public void setSizeArray(int[] sizeArray) { 498 this.sizeArray = sizeArray; 499 } 500 501 }
Spring-MVC Controller部分: UserController.java
@RequestMapping("view_user") public String view_user(PageUtil p, HttpServletRequest request) { //……仅提供部分关键代码 //分页组件用法:首先获取所有List List<User> list = userService.getUserList(); pu.init(list, pu.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
效果预览: