本文主要介绍在jsp中实现分页功能和页面跳转功能,能够实现数据的分页显示和跳转到指定页面的功能,具体效果如图
由于该功能是一个书城项目的一部分,所以数据来源于该项目,具体数据库(数据库方面采用c3p0连接池,使用的是mysql数据库)文件可以在点击打开链接下载,整个项目可以在点击打开链接下载(不过由于使用的是MyeElipse2013,所以请使用此版本或者更高版本导入工程)。
下面具体介绍一下这个小功能
1. 这个项目的目录结构:
2.显示的数据主要是图书的相关信息因此Bean类是图书Book的相关信息即com.page.book.domain中Book类的相关信息如下
package com.page.book.domain; import org.apache.log4j.Category; public class Book { private String bid;//主键 private String bname;//图名 private String author;//作者 private double price;//定价 private double currPrice;//当前价 private double discount;//折扣 private String press;//出版社 private String publishtime;//出版时间 private int edition;//版次 private int pageNum;//页数 private int wordNum;//字数 private String printtime;//刷新时间 private int booksize;//开本 private String paper;//纸质 private Category category;//所属分类 private String image_w;//大图路径 private String image_b;//小图路径 public String getBid() { return bid; } public void setBid(String bid) { this.bid = bid; } public String getBname() { return bname; } public void setBname(String bname) { this.bname = bname; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public double getCurrPrice() { return currPrice; } public void setCurrPrice(double currPrice) { this.currPrice = currPrice; } public double getDiscount() { return discount; } public void setDiscount(double discount) { this.discount = discount; } public String getPress() { return press; } public void setPress(String press) { this.press = press; } public String getPublishtime() { return publishtime; } public void setPublishtime(String publishtime) { this.publishtime = publishtime; } public int getEdition() { return edition; } public void setEdition(int edition) { this.edition = edition; } public int getPageNum() { return pageNum; } public void setPageNum(int pageNum) { this.pageNum = pageNum; } public int getWordNum() { return wordNum; } public void setWordNum(int wordNum) { this.wordNum = wordNum; } public String getPrinttime() { return printtime; } public void setPrinttime(String printtime) { this.printtime = printtime; } public int getBooksize() { return booksize; } public void setBooksize(int booksize) { this.booksize = booksize; } public String getPaper() { return paper; } public void setPaper(String paper) { this.paper = paper; } public Category getCategory() { return category; } public void setCategory(Category category) { this.category = category; } public String getImage_w() { return image_w; } public void setImage_w(String image_w) { this.image_w = image_w; } public String getImage_b() { return image_b; } public void setImage_b(String image_b) { this.image_b = image_b; } }3.dao层的实现
package com.page.book.dao; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import cn.itcast.jdbc.TxQueryRunner; import com.page.book.domain.Book; import com.page.pager.Expression; import com.page.pager.PageBean; import com.page.pager.PageConstants; public class BookDao { private QueryRunner qr = new TxQueryRunner(); /** * 按分类查询 * @param cid * @param pc * @return * @throws SQLException */ public PageBean<Book> findByCategory(String cid, int pc) throws SQLException { List<Expression> exprList = new ArrayList<Expression>(); exprList.add(new Expression("cid", "=", cid)); return findByCriteria(exprList, pc); } /** * 通用的查询方法 * @param exprList * @param pc * @return * @throws SQLException */ private PageBean<Book> findByCriteria(List<Expression> exprList, int pc) throws SQLException { /* * 1. 得到ps * 2. 得到tr * 3. 得到beanList * 4. 创建PageBean,返回 */ /* * 1. 得到ps */ int ps = PageConstants.BOOK_PAGE_SIZE;//每页记录数 /* * 2. 通过exprList来生成where子句 */ StringBuilder whereSql = new StringBuilder(" where 1=1"); List<Object> params = new ArrayList<Object>();//SQL中有问号,它是对应问号的值 for(Expression expr : exprList) { /* * 添加一个条件上, * 1) 以and开头 * 2) 条件的名称 * 3) 条件的运算符,可以是=、!=、>、< ... is null,is null没有值 * 4) 如果条件不是is null,再追加问号,然后再向params中添加一与问号对应的值 */ whereSql.append(" and ").append(expr.getName()) .append(" ").append(expr.getOperator()).append(" "); // where 1=1 and bid = ? if(!expr.getOperator().equals("is null")) { whereSql.append("?"); params.add(expr.getValue()); } } /* * 3. 总记录数 */ String sql = "select count(*) from t_book" + whereSql; Number number = (Number)qr.query(sql, new ScalarHandler(), params.toArray()); int tr = number.intValue();//得到了总记录数 /* * 4. 得到beanList,即当前页记录 */ sql = "select * from t_book" + whereSql + " order by orderBy limit ?,?"; params.add((pc-1) * ps);//当前页首行记录的下标 params.add(ps);//一共查询几行,就是每页记录数 List<Book> beanList = qr.query(sql, new BeanListHandler<Book>(Book.class), params.toArray()); /* * 5. 创建PageBean,设置参数 */ PageBean<Book> pb = new PageBean<Book>(); /* * 其中PageBean没有url,这个任务由Servlet完成 */ pb.setBeanList(beanList); pb.setPc(pc); pb.setPs(ps); pb.setTr(tr); return pb; } }4.service层的实现
package com.page.book.service; import java.sql.SQLException; import com.page.book.dao.BookDao; import com.page.book.domain.Book; import com.page.pager.PageBean; public class BookService { private BookDao bookDao = new BookDao(); /** * 按分类查 * @param cid * @param pc * @return */ public PageBean<Book> findByCategory(String cid, int pc) { try { return bookDao.findByCategory(cid, pc); } catch (SQLException e) { throw new RuntimeException(e); } } }5.servlet的实现
package com.page.book.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.itcast.servlet.BaseServlet; import com.page.book.domain.Book; import com.page.book.service.BookService; import com.page.pager.PageBean; public class BookServlet extends BaseServlet { /** * */ private static final long serialVersionUID = 1L; private BookService bookService = new BookService(); /** * 获取当前页码 * @param req * @return */ private int getPc(HttpServletRequest req) { int pc = 1; String param = req.getParameter("pc"); if(param != null && !param.trim().isEmpty()) { try { pc = Integer.parseInt(param); } catch(RuntimeException e) {} } return pc; } /** * 截取url,页面中的分页导航中需要使用它做为超链接的目标! * @param req * @return */ /* * http://localhost:8080/goods/BookServlet?methed=findByCategory&cid=xxx&pc=3 * /goods/BookServlet + methed=findByCategory&cid=xxx&pc=3 */ private String getUrl(HttpServletRequest req) { String url = req.getRequestURI() + "?" + req.getQueryString(); System.out.println("url:"+url); /* * 如果url中存在pc参数,截取掉,如果不存在那就不用截取。 */ int index = url.lastIndexOf("&pc="); if(index != -1) { url = url.substring(0, index); } return url; } public String findByCategory(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException { /* * 1. 得到pc:如果页面传递,使用页面的,如果没传,pc=1 */ int pc = getPc(req); /* * 2. 得到url:... */ String url = getUrl(req); System.out.println("url----"+url); /* * 3. 获取查询条件,本方法就是cid,即分类的id */ String cid = req.getParameter("cid"); /* * 4. 使用pc和cid调用service#findByCategory得到PageBean */ PageBean<Book> pb = bookService.findByCategory(cid, pc); /* * 5. 给PageBean设置url,保存PageBean,转发到/jsps/book/list.jsp */ pb.setUrl(url); req.setAttribute("pb", pb); return "f:/pager/pager.jsp";//f代表转发 } }6.关于分页的相关类的实现
package com.page.pager; public class PageConstants { public static final int BOOK_PAGE_SIZE = 12;//图书每页记录数 }7.pageBean的实现
package com.page.pager; import java.util.List; /** * 分页Bean,它会在各层之间传递 * * @param <T> */ public class PageBean<T> { private int pc;//当前页码 private int tr;//总记录数 private int ps;//每页记录数 private String url;//请求路径和参数,例如BookServlet?method=findXXX&cid=1&bname=2 private List<T> beanList; // 计算总页数 public int getTp() { int tp = tr / ps; return tr % ps == 0 ? tp : tp + 1; } public int getPc() { return pc; } public void setPc(int pc) { this.pc = pc; } public int getTr() { return tr; } public void setTr(int tr) { this.tr = tr; } public int getPs() { return ps; } public void setPs(int ps) { this.ps = ps; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public List<T> getBeanList() { return beanList; } public void setBeanList(List<T> beanList) { this.beanList = beanList; } }8.数据库辅助类
package com.page.pager; public class Expression { private String name; private String operator; private String value; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getOperator() { return operator; } public void setOperator(String operator) { this.operator = operator; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } @Override public String toString() { return "Expression [name=" + name + ", operator=" + operator + ", value=" + value + "]"; } public Expression() { super(); // TODO Auto-generated constructor stub } public Expression(String name, String operator, String value) { super(); this.name = name; this.operator = operator; this.value = value; toString(); } }9.c3p0文件的配置
<?xml version="1.0" encoding="UTF-8" ?> <c3p0-config> <default-config> <property name="jdbcUrl"> <![CDATA[ jdbc:mysql://localhost:3306/goods?useUnicode=true&characterEncoding=UTF8&useServerPrepStmts=true&prepStmtCacheSqlLimit=256&cachePrepStmts=true&prepStmtCacheSize=256&rewriteBatchedStatements=true ]]> </property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password">906363842aq</property> <property name="acquireIncrement">3</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">2</property> <property name="maxPoolSize">10</property> </default-config> </c3p0-config>10.分页前端的操作
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <link rel="stylesheet" type="text/css" href="<c:url value='/pager/pager.css'/>" /> <script type="text/javascript" src="<c:url value='/pager/jquery-1.5.1.js'/>"></script> <script type="text/javascript"> function _go() { var pc = $("#pageCode").val();//获取文本框中的当前页码 if(!/^[1-9]\d*$/.test(pc)) {//对当前页码进行整数校验 alert('请输入正确的页码!'); return; } if(pc > ${pb.tp}) {//判断当前页码是否大于最大页 alert('请输入正确的页码!'); return; } location = "${pb.url}&pc=" + pc; } </script> <table border="1"> <tr> <th>书名</th> <th>书价</th> <th>折扣</th> <th>作者</th> <th>出版社</th> <th>出版时间</th> </tr> <c:forEach items="${pb.beanList }" var="book"> <tr> <td>${book.bname }</td> <td>${book.price }</td> <td>${book.discount }折</td> <td>${book.author }</td> <td>${book.press }</td> <td>${book.publishtime }</td> </tr> </c:forEach> </table> <div class="divBody"> <div class="divContent"> <%--上一页 --%> <c:choose> <c:when test="${pb.pc eq 1 }"><span class="spanBtnDisabled">上一页</span></c:when> <c:otherwise><a href="${pb.url }&pc=${pb.pc-1}" class="aBtn bold">上一页</a></c:otherwise> </c:choose> <%--我们需要计算页码列表的开始和结束位置,即两个变量begin和end 计算它们需要通过当前页码! 1. 总页数不足6页--> begin=1, end=最大页 2. 通过公式设置begin和end,begin=当前页-1,end=当前页+3 3. 如果begin<1,那么让begin=1,end=6 4. 如果end>tp, 让begin=tp-5, end=tp --%> <c:choose> <c:when test="${pb.tp <= 6 }"> <c:set var="begin" value="1"/> <c:set var="end" value="${pb.tp }"/> </c:when> <c:otherwise> <c:set var="begin" value="${pb.pc-2 }"/> <c:set var="end" value="${pb.pc + 3}"/> <c:if test="${begin < 1 }"> <c:set var="begin" value="1"/> <c:set var="end" value="6"/> </c:if> <c:if test="${end > pb.tp }"> <c:set var="begin" value="${pb.tp-5 }"/> <c:set var="end" value="${pb.tp }"/> </c:if> </c:otherwise> </c:choose> <c:forEach begin="${begin }" end="${end }" var="i"> <c:choose> <c:when test="${i eq pb.pc }"> <span class="spanBtnSelect">${i }</span> </c:when> <c:otherwise> <a href="${pb.url }&pc=${i}" class="aBtn">${i }</a> </c:otherwise> </c:choose> </c:forEach> <%-- 计算begin和end --%> <%-- 如果总页数<=6,那么显示所有页码,即begin=1 end=${pb.tp} --%> <%-- 设置begin=当前页码-2,end=当前页码+3 --%> <%-- 如果begin<1,那么让begin=1 end=6 --%> <%-- 如果end>最大页,那么begin=最大页-5 end=最大页 --%> <%-- 显示点点点 --%> <c:if test="${end < pb.tp }"> <span class="spanApostrophe">...</span> </c:if> <%--下一页 --%> <c:choose> <c:when test="${pb.pc eq pb.tp }"><span class="spanBtnDisabled">下一页</span></c:when> <c:otherwise><a href="${pb.url }&pc=${pb.pc+1}" class="aBtn bold">下一页</a></c:otherwise> </c:choose> <%-- 共N页 到M页 --%> <span>共${pb.tp }页</span> <span>到</span> <input type="text" class="inputPageCode" id="pageCode" value="${pb.pc }"/> <span>页</span> <a href="javascript:_go();" class="aSubmit">确定</a> </div> </div>到这里就实现了分页的功能和页面跳转的功能,如果有什么问题可以留言,谢谢!