分页实现

it2022-05-16  74

  对于web应用来说分页显示数据是是最基本的功能,作为经常开发web应用的程序员来说这个功能也小菜一碟。闲着没事就把分页的实现写出来以便大家参考,不当之处欢迎批评指正。

1. 分页类(Page<T>

1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.regex.Pattern; 4 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 8 import org.apache.commons.lang3.StringUtils; 9 10 import com.fasterxml.jackson.annotation.JsonIgnore; 11 12 import com.common.utils.CookieUtils; 13 14 /** 15 * 分页类 16 * @author libingbin 17 * @version 1.0 18 * @param <T> 19 */ 20 public class Page<T> { 21 22 protected int pageNo = 1; // 当前页码 23 protected int pageSize = 15; // 页面大小,设置为“-1”表示不进行分页(分页无效) 24 25 protected long count;// 总记录数,设置为“-1”表示不查询总数 26 27 protected int first;// 首页索引 28 protected int last;// 尾页索引 29 protected int prev;// 上一页索引 30 protected int next;// 下一页索引 31 32 private boolean firstPage;//是否是第一页 33 private boolean lastPage;//是否是最后一页 34 35 protected int length = 8;// 显示页面长度 36 protected int slider = 1;// 前后显示页面长度 37 38 private List<T> list = new ArrayList<T>(); 39 40 private String orderBy = ""; // 标准查询有效, 实例: updatedate desc, name asc 41 42 protected String funcName = "page"; // 设置点击页码调用的js函数名称,默认为page,在一页有多个分页对象时使用。 43 44 protected String funcParam = ""; // 函数的附加参数,第三个参数值。 45 46 private String message = ""; // 设置提示消息,显示在“共n条”之后 47 48 public Page() { 49 this.pageSize = -1; 50 } 51 52 /** 53 * 构造方法 54 * @param request 传递 repage 参数,来记住页码 55 * @param response 用于设置 Cookie,记住页码 56 */ 57 public Page(HttpServletRequest request, HttpServletResponse response){ 58 this(request, response, -2); 59 } 60 61 /** 62 * 构造方法 63 * @param request 传递 repage 参数,来记住页码 64 * @param response 用于设置 Cookie,记住页码 65 * @param defaultPageSize 默认分页大小,如果传递 -1 则为不分页,返回所有数据 66 */ 67 public Page(HttpServletRequest request, HttpServletResponse response, int defaultPageSize){ 68 // 设置页码参数(传递repage参数,来记住页码) 69 String no = request.getParameter("pageNo"); 70 if (StringUtils.isNumeric(no)){ 71 CookieUtils.setCookie(response, "pageNo", no); 72 this.setPageNo(Integer.parseInt(no)); 73 }else if (request.getParameter("repage")!=null){ 74 no = CookieUtils.getCookie(request, "pageNo"); 75 if (StringUtils.isNumeric(no)){ 76 this.setPageNo(Integer.parseInt(no)); 77 } 78 } 79 // 设置页面大小参数(传递repage参数,来记住页码大小) 80 String size = request.getParameter("pageSize"); 81 if (StringUtils.isNumeric(size)){ 82 CookieUtils.setCookie(response, "pageSize", size); 83 this.setPageSize(Integer.parseInt(size)); 84 }else if (request.getParameter("repage")!=null){ 85 no = CookieUtils.getCookie(request, "pageSize"); 86 if (StringUtils.isNumeric(size)){ 87 this.setPageSize(Integer.parseInt(size)); 88 } 89 }else if (defaultPageSize != -2){ 90 this.pageSize = defaultPageSize; 91 } 92 // 设置排序参数 93 String orderBy = request.getParameter("orderBy"); 94 if (StringUtils.isNotBlank(orderBy)){ 95 this.setOrderBy(orderBy); 96 } 97 } 98 99 /** 100 * 构造方法 101 * @param pageNo 当前页码 102 * @param pageSize 分页大小 103 */ 104 public Page(int pageNo, int pageSize) { 105 this(pageNo, pageSize, 0); 106 } 107 108 /** 109 * 构造方法 110 * @param pageNo 当前页码 111 * @param pageSize 分页大小 112 * @param count 数据条数 113 */ 114 public Page(int pageNo, int pageSize, long count) { 115 this(pageNo, pageSize, count, new ArrayList<T>()); 116 } 117 118 /** 119 * 构造方法 120 * @param pageNo 当前页码 121 * @param pageSize 分页大小 122 * @param count 数据条数 123 * @param list 本页数据对象列表 124 */ 125 public Page(int pageNo, int pageSize, long count, List<T> list) { 126 this.setCount(count); 127 this.setPageNo(pageNo); 128 this.pageSize = pageSize; 129 this.list = list; 130 } 131 132 /** 133 * 初始化参数 134 */ 135 public void initialize(){ 136 137 //1 138 this.first = 1; 139 140 this.last = (int)(count / (this.pageSize < 1 ? 20 : this.pageSize) + first - 1); 141 142 if (this.count % this.pageSize != 0 || this.last == 0) { 143 this.last++; 144 } 145 146 if (this.last < this.first) { 147 this.last = this.first; 148 } 149 150 if (this.pageNo <= 1) { 151 this.pageNo = this.first; 152 this.firstPage=true; 153 } 154 155 if (this.pageNo >= this.last) { 156 this.pageNo = this.last; 157 this.lastPage=true; 158 } 159 160 if (this.pageNo < this.last - 1) { 161 this.next = this.pageNo + 1; 162 } else { 163 this.next = this.last; 164 } 165 166 if (this.pageNo > 1) { 167 this.prev = this.pageNo - 1; 168 } else { 169 this.prev = this.first; 170 } 171 172 //2 173 if (this.pageNo < this.first) {// 如果当前页小于首页 174 this.pageNo = this.first; 175 } 176 177 if (this.pageNo > this.last) {// 如果当前页大于尾页 178 this.pageNo = this.last; 179 } 180 181 } 182 183 /** 184 * 默认输出当前分页标签 185 * <div class="page">${page}</div> 186 */ 187 @Override 188 public String toString() { 189 190 StringBuilder sb = new StringBuilder(); 191 sb.append("<div class=\"fixed-table-pagination\" style=\"display: block;\">"); 192 193 long startIndex = (pageNo-1)*pageSize + 1; 194 long endIndex = pageNo*pageSize <=count? pageNo*pageSize:count; 195 196 sb.append("<div class=\"pull-left pagination-detail\">"); 197 sb.append("<span class=\"pagination-info\">显示第 "+startIndex+" 到第 "+ endIndex +" 条记录,总共 "+count+" 条记录</span>"); 198 sb.append("<span class=\"page-list\">每页显示 <span class=\"btn-group dropup\">"); 199 sb.append("<button type=\"button\" class=\"btn btn-default btn-outline dropdown-toggle\" data-toggle=\"dropdown\" aria-expanded=\"false\">"); 200 sb.append("<span class=\"page-size\">"+pageSize+"</span> <span class=\"caret\"></span>"); 201 sb.append("</button>"); 202 sb.append("<ul class=\"dropdown-menu\" role=\"menu\">"); 203 sb.append("<li class=\""+getSelected(pageSize,10)+ "\"><a href=\"javascript:"+funcName+"("+pageNo+",10,'"+funcParam+"');\">10</a></li>"); 204 sb.append("<li class=\""+getSelected(pageSize,25)+ "\"><a href=\"javascript:"+funcName+"("+pageNo+",25,'"+funcParam+"');\">25</a></li>"); 205 sb.append("<li class=\""+getSelected(pageSize,50)+ "\"><a href=\"javascript:"+funcName+"("+pageNo+",50,'"+funcParam+"');\">50</a></li>"); 206 sb.append("<li class=\""+getSelected(pageSize,100)+ "\"><a href=\"javascript:"+funcName+"("+pageNo+",100,'"+funcParam+"');\">100</a></li>"); 207 sb.append("</ul>"); 208 sb.append("</span> 条记录</span>"); 209 sb.append("</div>"); 210 211 212 sb.append("<div class=\"pull-right pagination-roll\">"); 213 sb.append("<ul class=\"pagination pagination-outline\">"); 214 if (pageNo == first) {// 如果是首页 215 sb.append("<li class=\"paginate_button previous disabled\"><a href=\"javascript:\"><i class=\"fa fa-angle-double-left\"></i></a></li>\n"); 216 sb.append("<li class=\"paginate_button previous disabled\"><a href=\"javascript:\"><i class=\"fa fa-angle-left\"></i></a></li>\n"); 217 } else { 218 sb.append("<li class=\"paginate_button previous\"><a href=\"javascript:\" οnclick=\""+funcName+"("+first+","+pageSize+",'"+funcParam+"');\"><i class=\"fa fa-angle-double-left\"></i></a></li>\n"); 219 sb.append("<li class=\"paginate_button previous\"><a href=\"javascript:\" οnclick=\""+funcName+"("+prev+","+pageSize+",'"+funcParam+"');\"><i class=\"fa fa-angle-left\"></i></a></li>\n"); 220 } 221 222 int begin = pageNo - (length / 2); 223 224 if (begin < first) { 225 begin = first; 226 } 227 228 int end = begin + length - 1; 229 230 if (end >= last) { 231 end = last; 232 begin = end - length + 1; 233 if (begin < first) { 234 begin = first; 235 } 236 } 237 238 if (begin > first) { 239 int i = 0; 240 for (i = first; i < first + slider && i < begin; i++) { 241 sb.append("<li class=\"paginate_button \"><a href=\"javascript:\" οnclick=\""+funcName+"("+i+","+pageSize+",'"+funcParam+"');\">" 242 + (i + 1 - first) + "</a></li>\n"); 243 } 244 if (i < begin) { 245 sb.append("<li class=\"paginate_button disabled\"><a href=\"javascript:\">...</a></li>\n"); 246 } 247 } 248 249 for (int i = begin; i <= end; i++) { 250 if (i == pageNo) { 251 sb.append("<li class=\"paginate_button active\"><a href=\"javascript:\">" + (i + 1 - first) 252 + "</a></li>\n"); 253 } else { 254 sb.append("<li class=\"paginate_button \"><a href=\"javascript:\" οnclick=\""+funcName+"("+i+","+pageSize+",'"+funcParam+"');\">" 255 + (i + 1 - first) + "</a></li>\n"); 256 } 257 } 258 259 if (last - end > slider) { 260 sb.append("<li class=\"paginate_button disabled\"><a href=\"javascript:\">...</a></li>\n"); 261 end = last - slider; 262 } 263 264 for (int i = end + 1; i <= last; i++) { 265 sb.append("<li class=\"paginate_button \"><a href=\"javascript:\" οnclick=\""+funcName+"("+i+","+pageSize+",'"+funcParam+"');\">" 266 + (i + 1 - first) + "</a></li>\n"); 267 } 268 269 if (pageNo == last) { 270 sb.append("<li class=\"paginate_button next disabled\"><a href=\"javascript:\"><i class=\"fa fa-angle-right\"></i></a></li>\n"); 271 sb.append("<li class=\"paginate_button next disabled\"><a href=\"javascript:\"><i class=\"fa fa-angle-double-right\"></i></a></li>\n"); 272 } else { 273 sb.append("<li class=\"paginate_button next\"><a href=\"javascript:\" οnclick=\""+funcName+"("+next+","+pageSize+",'"+funcParam+"');\">" 274 + "<i class=\"fa fa-angle-right\"></i></a></li>\n"); 275 sb.append("<li class=\"paginate_button next\"><a href=\"javascript:\" οnclick=\""+funcName+"("+last+","+pageSize+",'"+funcParam+"');\">" 276 + "<i class=\"fa fa-angle-double-right\"></i></a></li>\n"); 277 } 278 279 280 sb.append("</ul>"); 281 sb.append("</div>"); 282 sb.append("</div>"); 283 284 return sb.toString(); 285 } 286 287 protected String getSelected(int pageNo, int selectedPageNo){ 288 if(pageNo == selectedPageNo){ 289 //return "selected"; 290 return "active"; 291 }else{ 292 return ""; 293 } 294 295 } 296 297 /** 298 * 获取分页HTML代码 299 * @return 300 */ 301 public String getHtml(){ 302 return toString(); 303 } 304 305 306 307 /** 308 * 获取设置总数 309 * @return 310 */ 311 public long getCount() { 312 return count; 313 } 314 315 /** 316 * 设置数据总数 317 * @param count 318 */ 319 public void setCount(long count) { 320 this.count = count; 321 if (pageSize >= count){ 322 pageNo = 1; 323 } 324 } 325 326 /** 327 * 获取当前页码 328 * @return 329 */ 330 public int getPageNo() { 331 return pageNo; 332 } 333 334 /** 335 * 设置当前页码 336 * @param pageNo 337 */ 338 public void setPageNo(int pageNo) { 339 this.pageNo = pageNo; 340 } 341 342 /** 343 * 获取页面大小 344 * @return 345 */ 346 public int getPageSize() { 347 return pageSize; 348 } 349 350 /** 351 * 设置页面大小(最大500) 352 * @param pageSize 353 */ 354 public void setPageSize(int pageSize) { 355 this.pageSize = pageSize <= 0 ? 10 : pageSize;// > 500 ? 500 : pageSize; 356 } 357 358 /** 359 * 首页索引 360 * @return 361 */ 362 @JsonIgnore 363 public int getFirst() { 364 return first; 365 } 366 367 /** 368 * 尾页索引 369 * @return 370 */ 371 @JsonIgnore 372 public int getLast() { 373 return last; 374 } 375 376 /** 377 * 获取页面总数 378 * @return getLast(); 379 */ 380 @JsonIgnore 381 public int getTotalPage() { 382 return getLast(); 383 } 384 385 /** 386 * 是否为第一页 387 * @return 388 */ 389 @JsonIgnore 390 public boolean isFirstPage() { 391 return firstPage; 392 } 393 394 /** 395 * 是否为最后一页 396 * @return 397 */ 398 @JsonIgnore 399 public boolean isLastPage() { 400 return lastPage; 401 } 402 403 /** 404 * 上一页索引值 405 * @return 406 */ 407 @JsonIgnore 408 public int getPrev() { 409 if (isFirstPage()) { 410 return pageNo; 411 } else { 412 return pageNo - 1; 413 } 414 } 415 416 /** 417 * 下一页索引值 418 * @return 419 */ 420 @JsonIgnore 421 public int getNext() { 422 if (isLastPage()) { 423 return pageNo; 424 } else { 425 return pageNo + 1; 426 } 427 } 428 429 /** 430 * 获取本页数据对象列表 431 * @return List<T> 432 */ 433 public List<T> getList() { 434 return list; 435 } 436 437 /** 438 * 设置本页数据对象列表 439 * @param list 440 */ 441 public Page<T> setList(List<T> list) { 442 this.list = list; 443 initialize(); 444 return this; 445 } 446 447 /** 448 * 获取查询排序字符串 449 * @return 450 */ 451 @JsonIgnore 452 public String getOrderBy() { 453 // SQL过滤,防止注入 454 String reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|" 455 + "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)"; 456 Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE); 457 if (sqlPattern.matcher(orderBy).find()) { 458 return ""; 459 } 460 return orderBy; 461 } 462 463 /** 464 * 设置查询排序,标准查询有效, 实例: updatedate desc, name asc 465 */ 466 public void setOrderBy(String orderBy) { 467 this.orderBy = orderBy; 468 } 469 470 /** 471 * 获取点击页码调用的js函数名称 472 * function ${page.funcName}(pageNo){location="${ctx}/list-${category.id}${urlSuffix}?pageNo="+i;} 473 * @return 474 */ 475 @JsonIgnore 476 public String getFuncName() { 477 return funcName; 478 } 479 480 /** 481 * 设置点击页码调用的js函数名称,默认为page,在一页有多个分页对象时使用。 482 * @param funcName 默认为page 483 */ 484 public void setFuncName(String funcName) { 485 this.funcName = funcName; 486 } 487 488 /** 489 * 获取分页函数的附加参数 490 * @return 491 */ 492 @JsonIgnore 493 public String getFuncParam() { 494 return funcParam; 495 } 496 497 /** 498 * 设置分页函数的附加参数 499 * @return 500 */ 501 public void setFuncParam(String funcParam) { 502 this.funcParam = funcParam; 503 } 504 505 /** 506 * 设置提示消息,显示在“共n条”之后 507 * @param message 508 */ 509 public void setMessage(String message) { 510 this.message = message; 511 } 512 513 /** 514 * 分页是否有效 515 * @return this.pageSize==-1 516 */ 517 @JsonIgnore 518 public boolean isDisabled() { 519 return this.pageSize==-1; 520 } 521 522 /** 523 * 是否进行总数统计 524 * @return this.count==-1 525 */ 526 @JsonIgnore 527 public boolean isNotCount() { 528 return this.count==-1; 529 } 530 531 /** 532 * 获取 Hibernate FirstResult 533 */ 534 public int getFirstResult(){ 535 int firstResult = (getPageNo() - 1) * getPageSize(); 536 if (firstResult >= getCount() || firstResult<0) { 537 firstResult = 0; 538 } 539 return firstResult; 540 } 541 542 /** 543 * 获取 Hibernate MaxResults 544 */ 545 public int getMaxResults(){ 546 return getPageSize(); 547 } 548 549 550 551 }

 

2. 分页类(Page<T>)中的工具类【 import com.common.utils.CookieUtils】

1 import java.io.UnsupportedEncodingException; 2 import java.net.URLDecoder; 3 import java.net.URLEncoder; 4 5 import javax.servlet.http.Cookie; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 /** 10 * Cookie工具类 11 * @author libingbin 12 * @version 1.0 13 */ 14 public class CookieUtils { 15 16 /** 17 * 设置 Cookie(生成时间为1天) 18 * @param name 名称 19 * @param value 值 20 */ 21 public static void setCookie(HttpServletResponse response, String name, String value) { 22 setCookie(response, name, value, 60*60*24); 23 } 24 25 /** 26 * 设置 Cookie 27 * @param name 名称 28 * @param value 值 29 * @param maxAge 生存时间(单位秒) 30 * @param uri 路径 31 */ 32 public static void setCookie(HttpServletResponse response, String name, String value, String path) { 33 setCookie(response, name, value, path, 60*60*24); 34 } 35 36 /** 37 * 设置 Cookie 38 * @param name 名称 39 * @param value 值 40 * @param maxAge 生存时间(单位秒) 41 * @param uri 路径 42 */ 43 public static void setCookie(HttpServletResponse response, String name, String value, int maxAge) { 44 setCookie(response, name, value, "/", maxAge); 45 } 46 47 /** 48 * 设置 Cookie 49 * @param name 名称 50 * @param value 值 51 * @param maxAge 生存时间(单位秒) 52 * @param uri 路径 53 */ 54 public static void setCookie(HttpServletResponse response, String name, String value, String path, int maxAge) { 55 Cookie cookie = new Cookie(name, null); 56 cookie.setPath(path); 57 cookie.setMaxAge(maxAge); 58 try { 59 cookie.setValue(URLEncoder.encode(value, "utf-8")); 60 } catch (UnsupportedEncodingException e) { 61 e.printStackTrace(); 62 } 63 response.addCookie(cookie); 64 } 65 66 /** 67 * 获得指定Cookie的值 68 * @param name 名称 69 * @return 70 */ 71 public static String getCookie(HttpServletRequest request, String name) { 72 return getCookie(request, null, name, false); 73 } 74 /** 75 * 获得指定Cookie的值,并删除。 76 * @param name 名称 77 * @return 78 */ 79 public static String getCookie(HttpServletRequest request, HttpServletResponse response, String name) { 80 return getCookie(request, response, name, true); 81 } 82 /** 83 * 获得指定Cookie的值 84 * @param request 请求对象 85 * @param response 响应对象 86 * @param name 名字 87 * @param isRemove 是否移除 88 * @return 89 */ 90 public static String getCookie(HttpServletRequest request, HttpServletResponse response, String name, boolean isRemove) { 91 String value = null; 92 Cookie[] cookies = request.getCookies(); 93 if (cookies != null) { 94 for (Cookie cookie : cookies) { 95 if (cookie.getName().equals(name)) { 96 try { 97 value = URLDecoder.decode(cookie.getValue(), "utf-8"); 98 } catch (UnsupportedEncodingException e) { 99 e.printStackTrace(); 100 } 101 if (isRemove) { 102 cookie.setMaxAge(0); 103 response.addCookie(cookie); 104 } 105 } 106 } 107 } 108 return value; 109 } 110 }

 

3. Service基类中(查询分页数据的方法)

1 /** 2 * 查询分页数据 3 * @param page 分页对象 4 * @param entity 5 * @return 6 */ 7 public Page<T> findPage(Page<T> page, T entity) { 8 9 10 11 entity.setPage(page); //每个实体中需有当前实体分页对象封装为基类会比较方便protected Page<T> page; //当前实体分页对象 12 13 page.setList(dao.findList(entity)); //根据实体查询所有,返回结果为List集合 14 15 return page; 16 }

 

备注:

Controller层示例: 1 @RequestMapping(value = "list") 2 public String list(Demo demo, HttpServletRequest request, HttpServletResponse response, Model model) { 3 Page<Demo> page = DemoService.findPage(new Page<Demo>(request, response), demo); 4 model.addAttribute("page", page); 5 return "demo/demoList"; 6 }

 

 

4.  page.tag 标签【位置:/WEB-INF/tags/table/page.tag】

1 <%@ tag language="java" pageEncoding="UTF-8"%> 2 3 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 5 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 6 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 7 8 <%@ taglib prefix="table" tagdir="/WEB-INF/tags/table" %> 9 10 <c:set var="ctx" value="${pageContext.request.contextPath}${fns:getAdminPath()}"/> 11 <c:set var="ctxStatic" value="${pageContext.request.contextPath}/static"/> 12 13 <%@ attribute name="page" type="com.common.persistence.Page" required="true"%> 14 <%-- 表格分页工具栏,使用方法: 原样输出page --%> 15 ${page} 16 <!-- pagination的css样式设定--> 17 <style> 18 .fixed-table-pagination div.pagination, 19 .fixed-table-pagination div.pagination-roll, 20 .fixed-table-pagination .pagination-detail { 21 margin-top: 0px; 22 margin-bottom: 10px; 23 } 24 25 .fixed-table-pagination div.pagination-roll .pagination, 26 .fixed-table-pagination div.pagination .pagination { 27 margin: 0; 28 } 29 30 .fixed-table-pagination .pagination a { 31 padding: 6px 12px; 32 line-height: 1.428571429; 33 } 34 35 .fixed-table-pagination .pagination-info { 36 line-height: 34px; 37 margin-right: 5px; 38 } 39 40 .fixed-table-pagination .btn-group { 41 position: relative; 42 display: inline-block; 43 vertical-align: middle; 44 } 45 46 .fixed-table-pagination .dropup .dropdown-menu { 47 margin-bottom: 0; 48 } 49 50 .fixed-table-pagination .page-list { 51 display: inline-block; 52 } 53 54 </style>

 

5. 在jsp页面中只需要添加上述标签即可

1 <!-- 分页代码 --> 2 <table:page page="${page}"></table:page>

 

<!-- Start -->

获知及时信息,请关注我的个人微信订阅号:0与1的那点事

<!-- End -->

 

本文为博主原创文章,转载请注明出处!

http://www.cnblogs.com/libingbin/

感谢您的阅读。

转载于:https://www.cnblogs.com/libingbin/p/6361141.html

相关资源:数据结构—成绩单生成器

最新回复(0)