目录
一、通用分页准备工作
1、核心思路: 将上一次的查询请求再发一次,只不过是页码发生了改变!
2、PageBean中的三要素:
page 页码 视图层传递
rows 页数 视图层传递
totals 总记录数 后台查询出来
pagination 是否分页 视图层传递
3、后台
1.1 entity(实体类)和dao方法
注意:
1、 第一次查询条件的总记录数
2、 第二次查询满足条件的总记录数
而且两次查询的条件都要保持一致!
1.2 servlet 控制层
1.3 PageTag 视图层 也可以说是标签助手类
DBAccess类相当于之前我们写过的DBHelper类
EncodingFilter类是防止页面上的数据乱码
PageBean类是我自己写的关于分页的一些方法以及分页三要素
StringUtils类是防止字符串报空的!
相关jar包连接mysql
util包相关类;因为在做通用分页的过程中,怕页面上的数据乱码以及字符串报空等情况,需加入以下这些类:
二、各类的创建
实体类 Book.java
package com.lucy.entity;
public class Book {
private int bid;
private String bname;
private float price;
public int getBid() {
return bid;
}
public void setBid(int bid) {
this.bid = bid;
}
public String getBname() {
return bname;
}
public void setBname(String bname) {
this.bname = bname;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public Book(int bid, String bname, float price) {
this.bid = bid;
this.bname = bname;
this.price = price;
}
public Book(String bname, float price) {
this.bname = bname;
this.price = price;
}
public Book() {
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
}
}
PageBean类
import java.io.Serializable;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
public class PageBean implements Serializable {
//当前页码,默认第一页
private int page=1;
//每页多少条,默认10条
private int rows=10;
//总记录数,默认0
private int total=0;
//是否分页,默认分页
private boolean pagination=true;
//增强
//获取上一次请求的请求路径
// http://localhost:8080/pagination/bookAction.action
private String url;
//获取上一次请求的请求参数集合
private Map<String,String[]> params;
//基于mysql分页计算limit分页的开始位置
public int getStartIndex() {
//page=1 rows=10 (1-1)*10=0 limit 0,10
//page=2 rows=10 (2-1)*10=10 limit 10,10
//...
return (this.page-1)*this.rows;
}
public void setRequest(HttpServletRequest req) {
//获取前端传入的请求参数(分页三要素)
String page = req.getParameter("page");
String rows = req.getParameter("rows");
String pagination = req.getParameter("pagination");
this.setPage(page);
this.setRows(rows);
this.setPagination(pagination);
//获取上一次请求的请求路径
// http://localhost:8080/pagination/bookAction.action
// req.getRequestURI()==/pagination/bookAction.action
// req.getContextPath()==/pagination
// req.getServletPath()==/bookAction.action
this.url=req.getRequestURI();
// name="bookname" -> put("bookname",new String[]{"1"})
// <input type="hidden" name="bookname" value="1"/>
//获取上一次请求的请求参数 Map<String,String[]>
this.params=req.getParameterMap();
}
//获取最大页码
public int getMaxPager() {
int max=this.total/this.rows;
//判断是否有余数,取模。如果除不尽有余数,则最大页码+1
if(this.total%this.rows!=0)
max++;
return max;
}
//上一页
public int getProviousPager() {
int pro=this.page-1;
//判断页码
if(pro<1)
pro=1;
return pro;
}
//下一页
public int getNextPager() {
int next=this.page+1;
//判断页码是否超过最大页码
if(next>=this.getMaxPager())
next=this.getMaxPager();
return next;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map<String, String[]> getParams() {
return params;
}
public void setParams(Map<String, String[]> params) {
this.params = params;
}
public void setPage(String page) {
if(null!=page)
this.page = Integer.parseInt(page);
}
public void setRows(String rows) {
if(null!=rows)
this.rows = Integer.parseInt(rows);
}
public void setPagination(String pagination) {
if(null!=pagination)
this.pagination = Boolean.parseBoolean(pagination);
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public boolean isPagination() {
return pagination;
}
public void setPagination(boolean pagination) {
this.pagination = pagination;
}
@Override
public String toString() {
return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination
+ ", url=" + url + ", params=" + params + "]";
}
未封装的分页代码:
<div style="float:right;">
<form id="ff" action="${pageBean.getUrl() }" method="post">
<input type="hidden" name="page"/>
<!-- 在此处循环遍历pageBean中的params并动态生成input type="hidden" -->
</form>
第${pageBean.getPage() }页/共${pageBean.getMaxPager() }页
<a href="javascript:gotoPage(1)">首页</a>
<a href="javascript:gotoPage(${pageBean.getProviousPager()})">上一页</a>
<a href="javascript:gotoPage(${pageBean.getNextPager()})">下一页</a>
<a href="javascript:gotoPage(${pageBean.getMaxPager()})">末页</a>
<input type="text" id="skip" style="width:15px"/>
<input type="button" value="GO" οnclick="javascript:skipPage(${pageBean.getMaxPager()})"/>
<script>
function gotoPage(p){
document.getElementById('ff').page.value=p;
document.getElementById('ff').submit();
}
function skipPage(max){
var page=document.getElementById('skip').value;
if(isNaN(page)||page<1||page>max){
alert('请输入1~'+max+'之间的数字!');
return false;
}
gotoPage(page);
}
</script>
</div>
封装后代码------------------------>
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import com.zking.pagination.util.PageBean;
public class PaginationTag extends BodyTagSupport {
private PageBean pageBean;
@Override
public int doEndTag() throws JspException {
return EVAL_PAGE;
}
@Override
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
out.write(toHtml());
} catch (Exception e) {
e.printStackTrace();
}
return SKIP_BODY;
}
private String toHtml() {
//判断是否分页
if(null==pageBean||!pageBean.isPagination())
return "";
else {
StringBuilder sb=new StringBuilder();
//TODO
sb.append("<div style=\"float:right\">");
//拼接Form表单
sb.append("<form id=\"pageBeanForm\" action=\""+pageBean.getUrl()+"\" method=\"post\">");
//设置page隐藏域
sb.append("<input type=\"hidden\" name=\"page\"/>");
//拼接请求参数集合
Map<String, String[]> map = pageBean.getMap();
//获取请求参数集合键值对
Set<Entry<String,String[]>> entrySet = map.entrySet();
//遍历请求参数键值对
for (Entry<String, String[]> entry : entrySet) {
//获取请求参数名,也就是来自于表单中的name属性名称
String name=entry.getKey();
//如果参数为page,则continue跳过
if(name.equals("page"))
continue;
//获取请求参数对应的值,String[]
String[] values=entry.getValue();
//遍历value值
for (String value : values) {
//拼接请求参数
sb.append("<input type='hidden' name='"+name+"' value='"+value+"'/>");
}
}
sb.append("</form>");
//拼接共几页/第几页
sb.append("共"+pageBean.getMaxPager()+"页/第"+pageBean.getPage()+"页,");
//拼接首页、上一页、下一页、末页
if(pageBean.getPage()==1)
sb.append("首页 上一页 ");
else {
sb.append("<a href=\"javascript:gotoPage(1)\">首页</a> ");
sb.append("<a href=\"javascript:gotoPage("+pageBean.getPreviousPager()+")\">上一页</a> ");
}
if(pageBean.getPage()==pageBean.getMaxPager())
sb.append("下一页 末页 ");
else {
sb.append("<a href=\"javascript:gotoPage("+pageBean.getNextPager()+")\">下一页</a> ");
sb.append("<a href=\"javascript:gotoPage("+pageBean.getMaxPager()+")\">末页</a> ");
}
//拼接跳转页码
sb.append("<input type=\"text\" id=\"p\" style=\"width:20px;\"/>");
sb.append("<input type=\"button\" value=\"GO\" οnclick=\"javascript:skipPage();\"/>");
//拼接javascript跳转方法
sb.append("<script type=\"text/javascript\">\r\n" +
"function gotoPage(page){\r\n" +
" document.getElementById(\"pageBeanForm\").page.value=page;\r\n" +
" document.getElementById(\"pageBeanForm\").submit();\r\n" +
"}");
sb.append("function skipPage(){\r\n" +
" var page=document.getElementById(\"p\").value;\r\n" +
" if(isNaN(page)||page<1||page>="+pageBean.getMaxPager()+"){\r\n" +
" alert('请输入1~"+pageBean.getMaxPager()+"之间数字!');\r\n" +
" return false;\r\n" +
" }\r\n" +
" gotoPage(page);\r\n" +
"}\r\n" +
"</script>");
sb.append("</div>");
return sb.toString();
}
}
public PageBean getPageBean() {
return pageBean;
}
public void setPageBean(PageBean pageBean) {
this.pageBean = pageBean;
}
}
.主界面展示
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="z" uri="/zking" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>主页</title>
</head>
<body>
<form action="bookAction.action" method="post">
<label>书本名称:</label><input type="text" name="bookname"/>
<input type="submit" value="查询"/>
</form>
<table width="100%" border="1" cellpadding="0" cellspacing="0">
<tr>
<th>书本编号</th>
<th>书本名称</th>
<th>书本拼音</th>
<th>书本价格</th>
<th>书本类型</th>
</tr>
<c:forEach items="${books }" var="b">
<tr>
<td>${b.book_id }</td>
<td>${b.book_name }</td>
<td>${b.book_name_pinyin }</td>
<td>${b.book_price }</td>
<td>${b.book_type }</td>
</tr>
</c:forEach>
</table>
<z:pagination pageBean="${pageBean }"/>
</body>
</html>