分页
分页大家都知道有逻辑分页和物理分页,逻辑分页:即将信息全部查询出来,然后通过代码去进去分页,并不是依赖于SQL。物理分页: 即SQL中采用了limit 关键字来进行分页。小菜鸟使用的一般当然就是物理分页了,limit直接使用多简单。 为什么要写这篇博客呢,一是因为分页也是公司中常用的技术点之一,二是上星期公司中的一个项目中的分页有问题,那个项目是外包出去一段时间然后拿回来的,刚好分页是别人写的,那个代码写的(大家懂得),只好自己再改一遍。所以想了想还是写篇博客记录下来,以后有类似的问题也可以直接拿来使用。
分页中最重要的就是五要素了,我叫它分页五要素,其中包括当前页数(currentPage),总页数(totalPage),总记录数(totalResult),当前页中显示的记录数(showCount),当前页中显示的数据(list)。 先说说物理分页吧,物理分页采用limit,当然了两种分页各有千秋,在此我就不多说了。limit 2,4 就是从3 开始查询,查询4条数据。因为其是从0开始的,所以是不包含头的。这里主要讲的是逻辑分页,逻辑分页,先查询出所有的数据,然后使用代码将其进行分页操作,话不多说,先上代码
package com.cn.platform.common.page; import java.util.Map; public class Page { private int showCount = 10; // 每页显示记录数 private int totalPage; // 总页数 private int totalResult; // 总记录数 private int currentPage; // 当前页 private int currentResult; // 当前记录起始索引 private boolean entityOrField; // true:需要分页的地方,传入的参数就是Page实体;false:需要分页的地方,传入的参数所代表的实体拥有Page属性 private String pageStr; // 最终页面显示的底部翻页导航,详细见:getPageStr(); private String orderColunm;// 排序条件 private String orderMode;// 排序方式 private Map<String, Object> queryParam; public int getTotalPage() { if (totalResult % showCount == 0) { if (totalResult == 0) { totalPage = 1; } else { totalPage = totalResult / showCount; } } else { totalPage = totalResult / showCount + 1; } return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getTotalResult() { return totalResult; } public void setTotalResult(int totalResult) { this.totalResult = totalResult; } public int getCurrentPage() { if (currentPage <= 0) currentPage = 1; if (currentPage > getTotalPage()) currentPage = getTotalPage(); return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public String getPageStr() { StringBuffer sb = new StringBuffer(); if (totalResult > 0) { sb.append(" <ul>\n"); if (currentPage == 1) { sb.append(" <li class=\"pageinfo\">首页</li>\n"); sb.append(" <li class=\"pageinfo\">上页</li>\n"); } else { sb.append(" <li><a href=\"#@\" onclick=\"nextPage(1)\">首页</a></li>\n"); sb.append(" <li><a href=\"#@\" onclick=\"nextPage(" + (currentPage - 1) + ")\">上页</a></li>\n"); } int showTag = 3; // 分页标签显示数量 int startTag = 1; if (currentPage > showTag) { startTag = currentPage - 1; } int endTag = startTag + showTag - 1; for (int i = startTag; i <= totalPage && i <= endTag; i++) { if (currentPage == i) sb.append("<li class=\"current\">" + i + "</li>\n"); else sb.append(" <li><a href=\"#@\" onclick=\"nextPage(" + i + ")\">" + i + "</a></li>\n"); } if (currentPage == totalPage) { sb.append(" <li class=\"pageinfo\">下页</li>\n"); sb.append(" <li class=\"pageinfo\">尾页</li>\n"); } else { sb.append(" <li><a href=\"#@\" onclick=\"nextPage(" + (currentPage + 1) + ")\">下页</a></li>\n"); sb.append(" <li><a href=\"#@\" onclick=\"nextPage(" + totalPage + ")\">尾页</a></li>\n"); } sb.append(" <li class=\"pageinfo\">第" + currentPage + "页</li>\n"); sb.append(" <li class=\"pageinfo\">共" + totalPage + "页</li>\n"); sb.append("</ul>\n"); sb.append("<script type=\"text/javascript\">\n"); sb.append("function nextPage(page){"); sb.append(" if(true && document.forms[0]){\n"); sb.append(" var url = document.forms[0].getAttribute(\"action\");\n"); sb.append(" if(url.indexOf('?')>-1){url += \"&" + (entityOrField ? "currentPage" : "page.currentPage") + "=\";}\n"); sb.append(" else{url += \"?" + (entityOrField ? "currentPage" : "page.currentPage") + "=\";}\n"); sb.append(" document.forms[0].action = url+page;\n"); sb.append(" document.forms[0].submit();\n"); sb.append(" }else{\n"); sb.append(" var url = document.location+'';\n"); sb.append(" if(url.indexOf('?')>-1){\n"); sb.append(" if(url.indexOf('currentPage')>-1){\n"); sb.append(" var reg = /currentPage=\\d*/g;\n"); sb.append(" url = url.replace(reg,'currentPage=');\n"); sb.append(" }else{\n"); sb.append(" url += \"&" + (entityOrField ? "currentPage" : "page.currentPage") + "=\";\n"); sb.append(" }\n"); sb.append(" }else{url += \"?" + (entityOrField ? "currentPage" : "page.currentPage") + "=\";}\n"); sb.append(" document.location = url + page;\n"); sb.append(" }\n"); sb.append("}\n"); sb.append("</script>\n"); } pageStr = sb.toString(); return pageStr; } public void setPageStr(String pageStr) { this.pageStr = pageStr; } public int getShowCount() { return showCount; } public void setShowCount(int showCount) { this.showCount = showCount; } public int getCurrentResult() { currentResult = (getCurrentPage() - 1) * getShowCount(); if (currentResult < 0) currentResult = 0; return currentResult; } public void setCurrentResult(int currentResult) { this.currentResult = currentResult; } public boolean isEntityOrField() { return entityOrField; } public void setEntityOrField(boolean entityOrField) { this.entityOrField = entityOrField; } public String getOrderColunm() { return orderColunm; } public void setOrderColunm(String orderColunm) { this.orderColunm = orderColunm; } public String getOrderMode() { return orderMode; } public void setOrderMode(String orderMode) { this.orderMode = orderMode; } public Map<String, Object> getQueryParam() { return queryParam; } public void setQueryParam(Map<String, Object> queryParam) { this.queryParam = queryParam; } public void setPageMessage(Page page,String orderColunm,String orderMode) { int totalPage = 0; if (page.getTotalResult() != 0 ) { if (page.getTotalResult()%page.getShowCount() > 0) { totalPage = page.getTotalResult()/page.getShowCount() + 1; }else{ totalPage = page.getTotalResult()/page.getShowCount(); } page.setTotalPage(totalPage); } page.setOrderColunm(orderColunm); page.setOrderMode(orderMode); } }
/** * 分页链接HTML */ function splitPageHtml2(divId, formId, totalRow, pageSize, pageNumber, totalPages, isSelectPage, isSelectSize, orderColunm, orderMode){ var splitStr = '<div class="sub_pages centers jushang">'; splitStr += '<div class="lefts">每页 <b>'+pageSize+'</b> 条 共 <b>'+totalRow+'</b>条记录 页码:<b>'+pageNumber+'</b> / <b>'+totalPages+'</b></div>'; splitStr+='<div class="rights">'; if (pageNumber == 1 || totalPages == 0) { //首页 splitStr += '<span class="sub_pages_item radiuss4"><i class="icon-double-angle-left left_sub right_sub"><a href="javascript:void(0)"></a></i></span>'; } else { //上一页 splitStr += '<span class="sub_pages_item radiuss4" onclick="javascript:splitPageLink(\''+divId+'\', \''+formId+'\', 1);"><i class="icon-double-angle-left left_sub right_sub"></i></span>'; } if (pageNumber == 1 || totalPages == 0) { //尾页 splitStr += '<span class="sub_pages_item radiuss4"><i class="icon-angle-left left_sub right_sub"><a href="javascript:void(0)"></a></i></span>'; } else { //下一页 splitStr += '<span class="sub_pages_item radiuss4" onclick="javascript:splitPageLink(\''+divId+'\', \''+formId+'\', ' + (pageNumber - 1) + ');"><i class="icon-angle-left left_sub right_sub"></i></span>'; } for (var i = 1; i <= totalPages; i++) { if (i == 2 && pageNumber - 4 > 1) { // splitStr += '<li><a href="javascript:void(0)">...</a></li>'; splitStr += '...'; i = pageNumber - 4; } else if (i == pageNumber + 4 && pageNumber + 4 < totalPages) { // splitStr += '<li><a href="javascript:void(0)">...</a></li>'; splitStr += '...'; i = totalPages - 1; } else { if (pageNumber == i) { // splitStr += '<li class="active"><a href="javascript:void(0)" style="color: #272727; font-size: 14px; text-decoration: none;">' + pageNumber + '</a></li>'; splitStr += '<span class="sub_pages_item sub_pages_item_num radiuss4 spi_on"><a href="javascript:void(0)">' + pageNumber + '</a></span>'; } else { // splitStr += '<li><a href="javascript:splitPageLink(\''+divId+'\', \''+formId+'\', ' + i + ');" style="color: #898989; font-size: 14px;">'; // splitStr += i; // splitStr += '</a></li>'; splitStr += '<span class="sub_pages_item sub_pages_item_num radiuss4" onclick="javascript:splitPageLink(\''+divId+'\', \''+formId+'\', ' + i + ');"><a href="javascript:splitPageLink(\''+divId+'\', \''+formId+'\', ' + i + ');">'; splitStr += i; splitStr += '</a></span>'; } } } if (pageNumber == totalPages || totalPages == 0) { splitStr += '<span class="sub_pages_item radiuss4"><i class="icon-angle-right left_sub right_sub"></i></span>'; } else { splitStr += '<span class="sub_pages_item radiuss4" onclick="javascript:splitPageLink(\''+divId+'\', \''+formId+'\', ' + (pageNumber + 1) + ');"><i class="icon-angle-right left_sub right_sub"></i></span>'; } if (pageNumber == totalPages || totalPages == 0) { splitStr += '<span class="sub_pages_item radiuss4"><i class="icon-double-angle-right left_sub right_sub"></i></span>'; } else { splitStr += '<span class="sub_pages_item radiuss4" onclick="javascript:splitPageLink(\''+divId+'\', \''+formId+'\', ' + totalPages + ');"><i class="icon-double-angle-right left_sub right_sub"></i></span>'; } if(isSelectPage == true){ splitStr += ' <select name="currentPage" onChange="splitPageLink(\''+divId+'\', \''+formId+'\', this.value);" style="width: 100px; height:25px;">'; for (var i = 1; i <= totalPages; i++) { if (i == pageNumber) { splitStr += '<option selected value="' + i + '">跳转到第' + i +'页</option>'; } else { splitStr += '<option value="' + i + '">跳转到第' + i+ '页</option>'; } } if(totalPages == 0){ splitStr += '<option value="0">无跳转数据</option>'; } splitStr += '</select>'; splitStr += ' '; }else{ splitStr += '<input type="hidden" name="currentPage"/>'; } /*if(isSelectSize == true){ splitStr += '<select name="showCount" onChange="splitPageLink(\''+divId+'\', \''+formId+'\', 1);" style="width: 80px; height:25px;">'; var optionStr = '<option value="10">每页10条</option>'; optionStr += '<option value="20">每页20条</option>'; optionStr += '<option value="40">每页40条</option>'; optionStr += '<option value="80">每页80条</option>'; optionStr += '<option value="100">每页100条</option>'; optionStr += '<option value="200">每页200条</option>'; optionStr = optionStr.replace('"' + pageSize + '"', '"' + pageSize + '" selected="selected"'); splitStr += optionStr; splitStr += '</select>'; }else{ splitStr += '<input type="hidden" name="showCount">'; } */ splitStr += ' 共<strong>' + totalRow + '</strong>条记录'; splitStr += ''; splitStr += '<input type="hidden" name="orderColunm" value="'+orderColunm+'"/>'; splitStr += '<input type="hidden" name="orderMode" value="'+orderMode+'"/>'; splitStr+='</div>'; splitStr+='<div class="cleans"></div>'; splitStr+='</div>'; return splitStr; }
/** * 分页链接处理 */ function splitPageLink(divId, formId, toPage){ //alert($("#" + formId + " select[name=pageNumber]").attr("name"));//input[name=pageNumber] $("#" + formId + " select[name=currentPage],input[name=currentPage] ").val(toPage); var url = $("#url").val(); var totalResult = $("#totalResult").val(); var basePath = $("#basePath").val(); var result = basePath+url+"?currentPage="+ toPage + "&totalResult=" + totalResult; ajaxContent(result); // 封装的ajax提交到后台的方法 }
分页其实也不难,不管是逻辑分页还是物理分页,最主要的是分页5要素之间的计算和转换,上面代码中都有详细的阐述。其中showCount是已知的,currentResult和list是查询出来的,currentPage是前台传递到后台的,而totalPage是根据currentResult和currentPage计算出来的,所以说相当于5要素都是已知的。