通用分页核心思路:将上一次查询请求再发一次,只不过页码变了
思路:
1)使用传统方式EL表达式直接在JSP页面中实现分页效果
2)通过JSP自定义标签方式实现分页效果
实体类
package com.zhouzhuolin.pagination.entity;
public class Book {
private int id;
private String bookname;
private float price;
private String booktype;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBookname() {
return bookname;
}
public void setBookname(String bookname) {
this.bookname = bookname;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public String getBooktype() {
return booktype;
}
public void setBooktype(String booktype) {
this.booktype = booktype;
}
public Book() {
super();
}
public Book(String bookname, float price, String booktype) {
super();
this.bookname = bookname;
this.price = price;
this.booktype = booktype;
}
public Book(int id, String bookname, float price, String booktype) {
super();
this.id = id;
this.bookname = bookname;
this.price = price;
this.booktype = booktype;
}
@Override
public String toString() {
return "Book [id=" + id + ", bookname=" + bookname + ", price=" + price + ", booktype=" + booktype + "]";
}
}
PageBean类增强
package com.zhouzhuolin.pagination.util;
import java.util.Map;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
/**
* 分页工具类
*
*/
public class PageBean {
private int page = 1;// 页码
private int rows = 10;// 页大小
private int total = 0;// 总记录数
private boolean pagination = true;// 是否分页
private String uri;//上一次请求路径
private Map<String, String[]> map;//上一次请求的所有参数
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public Map<String, String[]> getMap() {
return map;
}
public void setMap(Map<String, String[]> map) {
this.map = map;
}
public PageBean() {
super();
}
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 void setTotal(String total) {
this.total = Integer.parseInt(total);
}
public boolean isPagination() {
return pagination;
}
public void setPagination(boolean pagination) {
this.pagination = pagination;
}
/**
* 获得起始记录的下标
*
* @return
*/
public int getStartIndex() {
return (this.page - 1) * this.rows;
}
public void setPage(String page) {
if (null!=page&&!"".equals(page)) {
this.page=Integer.parseInt(page);
}
}
public void setRows(String rows) {
if (null!=rows&&!"".equals(rows)) {
this.rows=Integer.parseInt(rows);
}
}
public void setPagination(String pagination) {
if (null!=pagination&&!"".equals(pagination)) {
this.pagination=Boolean.parseBoolean(pagination);
}
}
public void setRequest(HttpServletRequest req) {
String page=req.getParameter("page");
this.setPage(page);
String rows=req.getParameter("rows");
this.setRows(rows);
String pagination=req.getParameter("pagination");
this.setPagination(pagination);
this.uri=req.getRequestURI();
this.map=req.getParameterMap();
}
// 最大页数
public int getMaxpager() {
int maxpager=this.total/this.rows;
if (this.total%this.rows!=0) {
maxpager++;
}
return maxpager;
}
// 上一页
public int getProivousPager() {
int proivousPager=this.page-1;
if (proivousPager<1) {
proivousPager=1;
}
return proivousPager;
}
// 下一页
public int getNextPager() {
int nextPager=this.page+1;
if (nextPager>=this.getMaxpager()) {
nextPager=this.getMaxpager();
}
return nextPager;
}
@Override
public String toString() {
return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination
+ ", uri=" + uri + ", map=" + map + "]";
}
}
jsp界面
<%@ 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="/zhouzhuolin" %>
<!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>Insert title here</title>
</head>
<!-- <script type="text/javascript">
function gotoPager(page) {
document.getElementById("pageBeanForm").page.value=page;
document.getElementById("pageBeanForm").submit();
}
function skipPager(maxpage) {
var skipPager=document.getElementById("skipPage").value;
if (isNaN(skipPager)||skipPager<1||skipPager>maxpage) {
alert('请输入1~'+maxpage+'的数字');
return false;
}
gotoPager(skipPager);
}
</script> -->
<body>
<form action="bookList.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>
<td>编号</td>
<td>书名</td>
<td>价格</td>
<td>类型</td>
</tr>
<c:forEach var="book" items="${list }">
<tr>
<td>${book.id }</td>
<td>${book.bookname }</td>
<td>${book.price }</td>
<td>${book.booktype }</td>
</tr>
</c:forEach>
</table>
<%-- <label>${pageBean}</label>
<form id="pageBeanForm" action="${pageBean.uri }" method="post">
<input type="hidden" name="page">
<div style="white:100%;height: 40px;line-height: 30px;text-align:right; ">
第${pageBean.page}页/共${pageBean.getMaxpager()}页 每页${pageBean.rows}条数据/总共${pageBean.total}条记录
<a href="javascript:gotoPager(1)">首页</a>
<a href="javascript:gotoPager(${pageBean.getProivousPager() })">上一页</a>
<a href="javascript:gotoPager(${pageBean.getNextPager() })">下一页</a>
<a href="javascript:gotoPager(${pageBean.getMaxpager() })">末页</a>
<input type="text" id="skipPage" style="width: 30px;">
<input type="button" value="GO" onclick="skipPager(${pageBean.getMaxpager() })">
</div>
</form> --%>
<z:pagination pageBean="${pageBean }"/>
</body>
</html>
自定义分页标签
package com.zhouzhuolin.pagination.tag;
import java.io.IOException;
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.zhouzhuolin.pagination.util.PageBean;
public class PaginationTag extends BodyTagSupport{
/**
*
*/
private static final long serialVersionUID = 6425800140813236136L;
public PaginationTag() {
}
private PageBean pageBean;
public PageBean getPageBean() {
return pageBean;
}
public void setPageBean(PageBean pageBean) {
this.pageBean = pageBean;
}
@Override
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
out.println(toHTML());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return EVAL_BODY_INCLUDE;
}
public String toHTML() {
StringBuffer sb=new StringBuffer();
sb.append("<form id=\"pageBeanForm\" action=\""+pageBean.getUri()+"\" method=\"post\">");
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="bookname"
String name=entry.getKey();
if ("page".equals(name)) {
continue;
}
String[] values=entry.getValue();
for (String value : values) {
sb.append("<input type='hidden' name='"+name+"' value='"+value+"'>");
}
}
sb.append("<div style=\"white:100%;height: 40px;line-height: 30px;text-align:right; \">");
sb.append("第"+pageBean.getPage()+"页/共"+pageBean.getMaxpager()+"页 ");
sb.append("每页"+pageBean.getRows()+"条数据/总共"+pageBean.getTotal()+"条记录 ");
// 封装首页。上一页。下一页。末页方法
sb.append("<a href=\"javascript:gotoPager(1)\">首页</a> ");
sb.append("<a href=\"javascript:gotoPager("+pageBean.getProivousPager()+")\">上一页</a> ");
sb.append("<a href=\"javascript:gotoPager("+pageBean.getNextPager()+")\">下一页</a> ");
sb.append("<a href=\"javascript:gotoPager("+pageBean.getMaxpager()+")\">末页</a> ");
sb.append("<input type=\"text\" id=\"skipPage\" style=\"width: 30px;\">");
sb.append("<input type=\"button\" value=\"GO\" οnclick=\"skipPager()\">");
sb.append("</div></form>");
sb.append("<script type=\"text/javascript\">function gotoPager(page) {\r\n" +
" document.getElementById(\"pageBeanForm\").page.value=page;\r\n" +
" document.getElementById(\"pageBeanForm\").submit();\r\n" +
" }");
sb.append("function skipPager() {\r\n" +
" var skipPager=document.getElementById(\"skipPage\").value;\r\n" +
" if (isNaN(skipPager)||skipPager<1||skipPager>"+pageBean.getMaxpager()+") {\r\n" +
" alert('请输入1~"+pageBean.getMaxpager()+"的数字');\r\n" +
" return false;\r\n" +
" }\r\n" +
" gotoPager(skipPager);\r\n" +
" }</script>");
return sb.toString();
}
}
tld文件
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
<!-- 代表标签库的版本号 -->
<tlib-version>1.0</tlib-version>
<!-- 代表jsp的版本 -->
<jsp-version>1.2</jsp-version>
<!-- 你的标签库的简称 -->
<short-name>l</short-name>
<!-- 你标签库的引用uri -->
<uri>/zhouzhuolin</uri>
<tag>
<!-- 标签名 -->
<name>pagination</name>
<!-- 标签工具类 -->
<tag-class>com.zhouzhuolin.pagination.tag.PaginationTag</tag-class>
<!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 -->
<body-content>empty</body-content>
<!-- 自定义标签的属性定义,请注意一定要在标签类中提供对应的get/set方法 -->
<attribute>
<!-- 自定义标签的属性名称 -->
<name>pageBean</name>
<!-- true表示必填 -->
<required>true</required>
<!-- true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
action层
package com.zhouzhuolin.pagination.action;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zhouzhuolin.pagination.dao.BookDao;
import com.zhouzhuolin.pagination.entity.Book;
import com.zhouzhuolin.pagination.util.PageBean;
public class ActionServlet extends HttpServlet{
private BookDao bookDao=new BookDao();
/**
*
*/
private static final long serialVersionUID = 5894068286409453997L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO
/*String uri=req.getRequestURI();
Map<String, String[]> parameterMap = req.getParameterMap();*/
Book book=new Book();
book.setBookname(req.getParameter("bookname"));
PageBean pageBean=new PageBean();
pageBean.setRequest(req);
List<Book> books=null;
try {
books = bookDao.queryBookList(book, pageBean);
} catch (InstantiationException | IllegalAccessException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
req.setAttribute("pageBean", pageBean);
req.setAttribute("list", books);
req.getRequestDispatcher("/index.jsp").forward(req, resp);
}
Dao层
package com.zhouzhuolin.pagination.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.zhouzhuolin.pagination.entity.Book;
import com.zhouzhuolin.pagination.util.DBAccess;
import com.zhouzhuolin.pagination.util.PageBean;
import com.zhouzhuolin.pagination.util.StringUtils;
public class BookDao extends BaseDao<Book>{
private Connection con=null;
private PreparedStatement ps=null;
private ResultSet rs=null;
public void addBook(Book book) {
try {
String sql="insert into book(bookname,price,booktype) values(?,?,?)";
con=DBAccess.getConnection();
ps=con.prepareStatement(sql);
ps.setString(1, book.getBookname());
ps.setFloat(2, book.getPrice());
ps.setString(3, book.getBooktype());
ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
DBAccess.close(con, ps, null);
}
}
public List<Book> queryBookList(Book book,PageBean pageBean) throws InstantiationException, IllegalAccessException, SQLException {
String sql="select *from book where 1=1";
if (StringUtils.isNotBlank(book.getBookname())) {
sql += " and bookname like '%"+book.getBookname()+"%' ";
}
return super.queryBookList(sql, Book.class, pageBean);
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException, SQLException {
BookDao bookDao=new BookDao();
Book book=new Book();
// book.setBookname("1");
PageBean pageBean = new PageBean();
pageBean.setPage(2);
pageBean.setRows(10);
// pageBean.setPagination(false);
int total = pageBean.getTotal();
List<Book> queryBookList = bookDao.queryBookList(book, pageBean);
for (Book book2 : queryBookList) {
System.out.println(book2);
}
}
}
通用方法层
package com.zhouzhuolin.pagination.dao;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.zhouzhuolin.pagination.entity.Book;
import com.zhouzhuolin.pagination.util.DBAccess;
import com.zhouzhuolin.pagination.util.PageBean;
import com.zhouzhuolin.pagination.util.StringUtils;
public class BaseDao<T> {
/**
*
* @param sql 传入的sql语句
* @param clz 传入的对象
* @param pageBean 分页
* @return
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public List<T> queryBookList(String sql,Class<?> clz,PageBean pageBean) throws SQLException, InstantiationException, IllegalAccessException {
Connection con=DBAccess.getConnection();
PreparedStatement ps=null;
ResultSet rs=null;
// 如果pageBean不等于空 并且 允许分页 则执行分页代码块
if (pageBean != null && pageBean.isPagination()) {
String CountSql=getCountSql(sql);
ps=con.prepareStatement(CountSql);
rs=ps.executeQuery();
if (rs.next()) {
pageBean.setTotal(rs.getLong(1)+"");
}
System.out.println("总记录数:"+pageBean.getTotal());
String PagerSql=getPagerSql(sql, pageBean);
ps=con.prepareStatement(PagerSql);
rs=ps.executeQuery();
}else {
ps=con.prepareStatement(sql);
rs=ps.executeQuery();
}
List<T> list=new ArrayList<T>();
T t;
while (rs.next()) {
// list.add(new Book(rs.getInt("id"), rs.getString("bookname"), rs.getFloat("price"), rs.getString("booktype")));
// 通过反射机制实例化 并且赋值
t=(T) clz.newInstance();
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
// getObject 因为不知道传过来是什么值 所以写个Object代替
field.set(t, rs.getObject(field.getName()));
}
list.add(t);
}
DBAccess.close(con, ps, rs);
return list;
}
// 获取总纪录数的sql语句
public String getCountSql(String sql) {
return "select count(*) from ("+sql+") t";
}
// 获取分页数据的sql语句
public String getPagerSql(String sql,PageBean pageBean) {
return sql+" limit "+pageBean.getStartIndex()+","+pageBean.getRows();
}
}
xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Y2_Pagination</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 处理乱码 过滤器 -->
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.zhouzhuolin.pagination.util.EncodingFiter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>ActionServlet</servlet-name>
<servlet-class>com.zhouzhuolin.pagination.action.ActionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
<url-pattern>/bookList.action</url-pattern>
</servlet-mapping>
</web-app>
中文乱码处理(过滤器)
package com.zhouzhuolin.pagination.util;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 中文乱码处理
*
*/
public class EncodingFiter implements Filter {
private String encoding = "UTF-8";// 默认字符集
public EncodingFiter() {
super();
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 中文处理必须放到 chain.doFilter(request, response)方法前面
res.setContentType("text/html;charset=" + this.encoding);
if (req.getMethod().equalsIgnoreCase("post")) {
req.setCharacterEncoding(this.encoding);
} else {
Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合
Set set = map.keySet();// 取出所有参数名
Iterator it = set.iterator();
while (it.hasNext()) {
String name = (String) it.next();
String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组]
for (int i = 0; i < values.length; i++) {
values[i] = new String(values[i].getBytes("ISO-8859-1"),
this.encoding);
}
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集
if (null != s && !s.trim().equals("")) {
this.encoding = s.trim();
}
}
}