本文主要介绍在jsp中实现分页功能和页面跳转功能,能够实现数据的分页显示和跳转到指定页面的功能,具体效果如图
由于该功能是一个书城项目的一部分,所以数据来源于该项目,具体数据库(数据库方面采用c3p0连接池,使用的是mysql数据库)文件可以在点击打开链接下载,整个项目可以在点击打开链接下载(不过由于使用的是MyeElipse2013,所以请使用此版本或者更高版本导入工程)。
下面具体介绍一下这个小功能
1. 这个项目的目录结构:
2.显示的数据主要是图书的相关信息因此Bean类是图书Book的相关信息即com.page.book.domain中Book类的相关信息如下
package com.page.book.domain;3.dao层的实现
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;
}
}
package com.page.book.dao;4.service层的实现
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;
}
}
package com.page.book.service;5.servlet的实现
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);
}
}
}
package com.page.book.servlet;6.关于分页的相关类的实现
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代表转发
}
}
package com.page.pager;7.pageBean的实现
public class PageConstants {
public static final int BOOK_PAGE_SIZE = 12;//图书每页记录数
}
package com.page.pager;8.数据库辅助类
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;
}
}
package com.page.pager;9.c3p0文件的配置
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();
}
}
<?xml version="1.0" encoding="UTF-8" ?>10.分页前端的操作
<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>
<%@ 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>