看到论坛上有同学在问关于分页的东西,我这里把自己一些分页的技巧整理下发上来...因为这是在实际项目使用的,,,所以跟其他一些业务方法有关联...还有就是使用了struts和JSTL(包括EL)标签库... 效果如下图: bean代码: /*
* 创建日期 2006-1-26 * @author Woden Wang * power by Heatpixel.com */ package org.woden.model; import org.woden.facade.IPageCutter; public class PageCutter implements IPageCutter{ private int pageLength=10; //每页最大显示记录数 private int totalRecord; //总记录数 private int currentPage=0; //当前页 private static final int LENGTH = 5; //分页间隔 /** * 判断当前页是否末页 * @return */ public boolean hasNextPage() { return currentPage<getTotalPage(); } /** * 判断当前页是否首页 * @return */ public boolean hasPreviousPage() { return currentPage>1; } /** * 判断是否出现逻辑错误 * @return */ public boolean hasError() { return (getCurrentPage()>getTotalPage()||getCurrentPage()<1); } /** * 获取当前页 * @return */ public int getCurrentPage() { return currentPage; } /** * 设置当前页 * @param currentPage */ public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } /** * 获取当前记录数 * @return */ public int getCurrentRecord() { if(currentPage==0) return 0; return pageLength*(currentPage-1); } /** * 获取页面长度 * @return */ public int getPageLength() { return pageLength; } /** * 设置页面长度 * @param pageLength */ public void setPageLength(int pageLength) { this.pageLength = pageLength; } /** * 获取页面总数 * @return */ public int getTotalPage() { return (totalRecord%pageLength==0)?totalRecord/pageLength:totalRecord/pageLength+1; } /** * 获取记录总数 * @return */ public int getTotalRecord() { return totalRecord; } /** * 设置记录总数 * @param totalRecord */ public void setTotalRecord(int totalRecord) { this.totalRecord = totalRecord; } /** * 页面循环开始 * @return */ public int getBeginPage() { int begin = this.currentPage - LENGTH; if(begin<=1) return 1; else return begin; } /** * 页面循环结束 * @return */ public int getEndPage() { int end = this.currentPage + LENGTH; if(end>=getTotalPage()) return getTotalPage(); else return end; } /** * 第一页 * @return */ public int getFirstPage() { return 1; } /** * 末页 * @return */ public int getLastPage() { return getTotalPage(); } } 说明下,这个bean实现的接口是我自己定义的,如果不是太复杂的java应用的话其实不需要用接口.(有兴趣了解接口的优势的朋友建议阅读"门面模式"的相关文章) 标签处理器类: /*
* 创建日期 2006-2-7 * @author Woden Wang * power by Heatpixel.com */ package org.woden.controller.tag; import org.apache.log4j.Logger; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.tagext.TagSupport; import org.woden.facade.IPageCutter; public class PageCut extends TagSupport{ /** * Logger for this class */ private static final Logger logger = Logger.getLogger(PageCut.class); private IPageCutter pageBean; private String file; public void setFile(String file) { this.file = filtePage(file); } public void setPageBean(IPageCutter pageBean) { this.pageBean = pageBean; } /** * 对路径进行特殊处理 * @param file * @return */ private static String filtePage(String file) { String querys = file.substring(file.indexOf("?")+1); String path = file.substring(0,file.indexOf("?")+1); String query[] = querys.split("&"); for(int i=0;i<query.length;i++) { if(query[i].startsWith("page=")||query[i].equals("")) continue; path+=query[i]+"&"; } return path.substring(0,path.length()-1); } public int doStartTag() { HttpServletRequest request = (HttpServletRequest)pageContext.getRequest(); if(file.equals("")||pageBean==null) return SKIP_BODY; try { request.setAttribute("path",this.file); request.setAttribute("pageBean",pageBean); pageContext.include("/templet/page_cutter.jsp"); } catch (Exception e) { logger.warn("获取页面文件失败."); } return SKIP_BODY; } } 以下是/templet/page_cutter.jsp的代码: CODE:
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="http://struts./tags-bean" prefix="bean"%> <%@ taglib uri="http://struts./tags-html" prefix="html"%> <%@ taglib uri="http://struts./tags-logic" prefix="logic"%> <%@ taglib uri="http://java./jstl/core" prefix="c"%> <!--分页--> <p> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td bgcolor="#f5f5f5" height="30"> <img src="images/spacer.gif" width="10" height="8"> <bean:message key="jsp.global.cutPage.current" /><%--显示"Current Page"--%> <span class="title">${pageBean.currentPage}</span> of ${pageBean.totalPage} </td> <td align="right" bgcolor="#f5f5f5"> <bean:message key="jsp.global.cutPage.click" /><%--显示"Click to View Page"--%> <c:if test="${pageBean.beginPage>1}"> <html:link page="${path}" paramId="page" paramName="pageBean" paramProperty="firstPage">${pageBean.firstPage}</html:link>...</c:if> <c:forEach begin="${pageBean.beginPage}" end="${pageBean.endPage}" step="1" var="i"> <c:if test="${i==pageBean.currentPage}"> <span class="title">${i}</span> </c:if> <c:if test="${i!=pageBean.currentPage}"> <html:link page="${path}" paramId="page" paramName="i">${i}</html:link> </c:if> </c:forEach> <c:if test="${pageBean.endPage<pageBean.totalPage}">...<html:link page="${path}" paramId="page" paramName="pageBean" paramProperty="lastPage">${pageBean.lastPage}</html:link> </c:if> <img src="images/spacer.gif" width="10" height="8" border="0" /> </td> </tr> </table> </p> 由于我用来struts框架,,,所以这里用到了struts的标签...其实如果没用struts的话也可以去处那些标签,也就是把<html:link>改成<a href=...>,,,把<bean:message>直接改成要显示的文字就可以了... <!--分页显示标签-->
<tag> <name>cutPage</name> <tag-class>org.woden.controller.tag.PageCut</tag-class> <body-content>jsp</body-content> <attribute> <name>file</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>pageBean</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> 标签调用文件(list.jsp),为了不影响大家阅读,,,这里省去了部分代码... <%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="http://struts./tags-bean" prefix="bean"%> <%@ taglib uri="http://struts./tags-html" prefix="html"%> <%@ taglib uri="http://struts./tags-logic" prefix="logic"%> <%@ taglib uri="http://struts./tags-tiles" prefix="tiles"%> <%@ taglib uri="business" prefix="business"%><%--用户业务标签库,包括分页标签就在这里定义--%> <bean:parameter name="page" id="currentPage" value="1" /> <%-- 这里省去了部分代码,代码实例会在后面讲解. --%> <table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#aaaaaa"> <tr style=" background-color:#eeeeee;text-align:center" class="titles"> <td height="28"> 测试的循环 </td> </tr> <logic:iterate id="news" name="list" type="org.woden.facade.news.INews"> <%-- 这里是业务循环标签,相当于把保存在list里面的每个news对象遍历出来, 大概可以理解成:从数据库读出的列表数据(可能总数100条,这里读出10条,分页嘛)放到list里面, 并返回一个pageCutter对象,大概的demo操作我下面会给出. --%> <!--循环开始--> <tr style=" background-color:#ffffff;text-align:center"> <td> <%--显示业务逻辑,,,已删除--%> </td> </tr> <!--循环结束--> </logic:iterate> </table> <%--pageCutter是分页对象名,这里调用标签将分页对象里面的内容显示出来--%> <business:cutPage file="${pageContext.request.servletPath}?${pageContext.request.queryString}" pageBean="${pageCutter}" /> 最后这里说说大概的数据库操作: 最后说明下,我是个追求良好设计模式很刻骨的人,,,所以可能会出现一些接口啊,,,门面层这类的,,,还有为了追求所谓的MVC,,,我在JSP页面也没写任何的java语句/表达式,,,取而代之的是EL和JSTL... -------------------------------------------------------------------------------------下面是非MVC的分页--------------------------------- 这个是asp式的分页...我从以前asp里面翻译过来的... <%@ page contentType="text/html;charset=gbk"%>
<%@ page import="java.sql.*"%> <%Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver") .newInstance(); String url = "jdbc:microsoft:sqlserver://localhost;DatabaseName=pagetest"; String user = "sa"; String password = ""; Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn .createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); String sql = "select * from test order by id";//这里的test里面只有两个字段,一个id(主键,自动增1),一个是test(vachar) ResultSet rs = stmt.executeQuery(sql); rs.last();//将记录游标移动到最末,从而计算出共有多少条记录,方便分页统计 if (rs.getRow() == 0) {//如果记录数为0就显示"没有内容" %> 没有内容 <% } else { //page module int count_per_page = 5; //每页5个记录 int page_on = 1; //当前页 int total_record = 0; //记录总数 int total_page = 0; //总页数 total_record = rs.getRow(); if (total_record % count_per_page == 0) total_page = total_record / count_per_page; else total_page = total_record / count_per_page + 1; if ("".equals(request.getParameter("page")) || request.getParameter("page") == null) page_on = 1; else page_on = Integer.parseInt(request.getParameter("page")); if (page_on > total_page) page_on = total_page; if (page_on <= 0) page_on = 1; rs.absolute((page_on - 1) * count_per_page + 1); //put index %> <% for (int i = 1; i <= count_per_page; i++) { %> <p> <%=rs.getString("test")%><%--这里循环显示数据--%> </p> <%if (!rs.next()) break; }//end for %> <%--show count--%> <% String filename = "list.jsp?"; int page_show_begin = 0; //began showed page int page_show_end = 0; //ended showed page int page_show_max = 6; //max showed page if ((page_on - 1) > page_show_max) page_show_begin = page_on - page_show_max + 1; else page_show_begin = 1; if (total_page - page_on > page_show_max) page_show_end = page_on + page_show_max - 1; else page_show_end = total_page; %> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td height="30"></td> <td bgcolor="#f5f5f5"> <img src="images/spacer.gif" width="10" height="8"> Currently Viewing Page <span class="title"><%=page_on%></span> of <%=total_page%> </td> <td align="right" bgcolor="#f5f5f5"> Click to View Page: <%if (page_show_begin != 1) {%> <%if (page_on == 1) {%> <span class="title"><%=page_on%></span> <%} else { %> <a href="<%=filename%>page=1">1</a> <%}%> ... <%}%> <%for (int a = page_show_begin; a <= page_show_end; a++) {%> <%if (a == page_on) {%> <span class="title"><%=a%></span> <%} else {%> <a href="<%=filename%>page=<%=a%>"><%=a%></a> <%}%> <%}%> <%if (page_show_end != total_page) {%> ... <%if (total_page == page_on) {%> <span class="title"><%=page_on%></span> <%} else { %> <a href="<%=filename%>page=<%=total_page%>"><%=total_page%></a> <%} } %> <img src="images/spacer.gif" width="10" height="8" border="0"> </td> </tr> </table> <%--View--%> <%} rs.close(); stmt.close(); conn.close(); %>
|
|