通用分页就是把我们经常使用的分页方法进行封装,然后用泛型传递对象,利用反射获取对象的所有属性并且赋值。
2、为何要使用通用分页?一般在实际项目的开发过程中我们会有很多数据的展示,并且数据量大,展示的数据种类繁多,这意味着我们要写很多重复的代码,我们可将重复相同的代码提取出来进行封装,后期进行调用即可。
3、通用分页核心思路:将上一次查询请求再发一次,只不过页码变了 4、环境配置(如何实现分页)1、明确我们的需求是什么?
2、在实际项目开发中分页需要哪些参数?页码(每页所展示的数据)、总记录数、是否分页、点击下一页或者上一页所需地址
PageBean 分页三要素 page 页码 视图层传递过来 rows 页大小 视图层传递过来 total 总记录数 后台查出来 pagination 是否分页 视图层传递过来 getStartIndex() 基于MySql数据库分页,获取分页开始标记
4.1.以书籍为例,创建一个书籍表,同时再创建一个书籍项目
create table t_book( book_id int not null primary key auto_increment comment '书本编号', book_name varchar(30) not null comment '书本名称', book_name_pinyin varchar(30) null comment '书本拼音', book_price float default 0 comment '书本价格', book_type varchar(10) not null comment '书本类型' )comment '书本信息表'; #分页(limit) #limit 参数1,参数2 (page-1)*rows #参数1:从第几条数据开始 #参数2:每次返回多少条数据 rows #第一页:从0开始,返回2条 #第二页:从2开始,返回2条
4.2.项目中的相关配置以及导入必要的依赖
依赖:
mysql-connector-java-5.1.44-bin.jar MySQL的驱动类
pinyin4j-2.5.0.jar 拼音的jar,作用是可以快速的将中文转变成英文,只提取拼音首字母
standard-1.1.2.jar jstl标签
jstl-1.2.jar
工具类:
CommonUtils.java 反射封装ResultSet结果集
DBHelper.java 连接数据库
config.properties 资源文件
EncodingFiter.java 中文乱码过滤器
StringUtils.java 判断字符串是否存在(为空)
PageTag.java 自定义标签的助手类
PageBean.java 分页工具类PinYinUtil.java 拼音工具类
4.3.先写一个分页工具类,用于实现分页效果。
package com.zking.pagination.util;
import java.io.Serializable;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
public class PageBean implements Serializable{
//当前页码,默认1
private int page=1;
//页面显示条数,默认10
private int rows=10;
//总记录数,默认0
private int total=0;
//是否分页标记,默认分页
private boolean pageination=true;
//http://localhost:8080/pagination/BookServlet.action
///pagination/BookServlet.action
//获取上一次请求路径
private String url;
//获取上一次请求的请求参数集合
// Map params=req.getParameterMap();
//
private Map params;
public PageBean() {
super();
}
public int getStartIndex() {
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.setPageination(pagination);
//获取上一次请求的请求路径
//http://localhost:8080/pagination/BookServlet.action
// req.getRequestURI()==等同于/pagination/BookServlet.action
// req.getContextPath()==项目名/pagination
// req.getServletPath()==请求路径/BookServlet.action
//当前路径
this.url = req.getRequestURI();
//获取上一次请求的请求参数集合
//Map-->params.put("bookname",new String[]{"",""})
this.params = req.getParameterMap();
}
public int getMaxPager() {
int p = this.total/this.rows;
//判断是否有余数,如果有余数,则最大页码+1
if(this.total%this.rows!=0)
p++;
return p;
}
public int getProviousPager() {
int p = this.page-1;
if(p<1)
p=1;
return p;
}
public int getNextPager() {
int p = this.page+1;
if(this.page>=this.getMaxPager())
p=this.getMaxPager();
return p;
}
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 setPageination(String pageination) {
if(null!=pageination)
this.pageination = Boolean.parseBoolean(pageination);
}
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 isPageination() {
return pageination;
}
public void setPageination(boolean pageination) {
this.pageination = pageination;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map getParams() {
return params;
}
public void setParams(Map params) {
this.params = params;
}
@Override
public String toString() {
return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pageination=" + pageination
+ ", url=" + url + ", params=" + params + "]";
}
}
BaseDao.java(是一个通用的父类方法,来帮助我们实现通用的分类)
package com.zking.pagination.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import com.zking.pagination.util.DBHelper; import com.zking.pagination.util.PageBean; public class BaseDao{ public static interface CallBack { //只用于遍历ResultSet结果集 public List foreachRs(ResultSet rs) throws SQLException; } public List excuteQuery(String sql,PageBean pageBean,CallBack callBack){ //声明对象 Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { //获取连接对象 conn = DBHelper.getConnection(); //根据pageBean分页对象判断是否分页 if(null!=pageBean&&pageBean.isPageination()) { //1.分页 //1)根据满足条件查询总记录数 String countSQL = this.getCountSQL(sql); //创建执行对象 stmt = conn.prepareStatement(countSQL); //执行sql语句并返回总记录数 rs = stmt.executeQuery(); //获取总记录数 if(rs.next()) { pageBean.setTotal(rs.getInt(1)); } //2)根据满足条件查询分页结果集 sql = this.getPagerSQL(sql, pageBean);//覆盖 } //创建执行对象 stmt = conn.prepareStatement(sql); //查询结果集 rs = stmt.executeQuery(); return callBack.foreachRs(rs); } catch (Exception e) { e.printStackTrace(); }finally { DBHelper.close(conn, stmt, rs); } return null; } private String getCountSQL(String sql) { return "select count(0) from ("+sql+") temp"; } private String getPagerSQL(String sql,PageBean pageBean) { return sql+" limit "+pageBean.getStartIndex()+","+pageBean.getRows(); } }
BookDao.java(dao类继承了BaseDao 父类,代码简洁,通用的方法都在父类中)
package com.zking.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 javax.management.RuntimeErrorException; import com.zking.pagination.entity.Book; import com.zking.pagination.util.DBHelper; import com.zking.pagination.util.PageBean; import com.zking.pagination.util.StringUtils; public class BookDao extends BaseDao{ //1、书本新增 public void addBook(Book book) { //声明对象 Connection conn = null; PreparedStatement stmt = null; try { //获取连接对象 conn= DBHelper.getConnection(); //定义sql语句 String sql = "insert into t_book(book_name,book_name_pinyin,book_price,book_type) values(?,?,?,?)"; //创建执行对象 stmt = conn.prepareStatement(sql); //参数赋值 stmt.setString(1, book.getBook_name()); stmt.setString(2, book.getBook_name_pinyin()); stmt.setFloat(3, book.getBook_price()); stmt.setString(4, book.getBook_type()); //执行sql语句并返回影响行数 int i = stmt.executeUpdate(); if(i<1) { throw new RuntimeException("影响行数为0,添加失败"); } } catch (Exception e) { e.printStackTrace(); }finally { DBHelper.close(conn, stmt, null); } } public List queryBookPager(Book book,PageBean pageBean){ //定义sql语句 String sql = "select book_id,book_name,book_name_pinyin,book_price,book_type from t_book where 1=1"; //拼接查询条件,按照书本名称模糊查询 if(StringUtils.isNotBlank(book.getBook_name())) sql+=" and book_name like '%"+book.getBook_name()+"%'"; //按照书本编号降序排序 sql+=" order by book_id desc"; System.out.println(sql); return super.excuteQuery(sql, pageBean, new CallBack () { @Override public List foreachRs(ResultSet rs) throws SQLException { List blist = new ArrayList<>(); //定义Book对象 Book b = null; //循环遍历结果集 while(rs.next()) { //创建Book对象 b = new Book(); b.setBook_id(rs.getInt("book_id")); b.setBook_name(rs.getString("book_name")); b.setBook_name_pinyin(rs.getString("book_name_pinyin")); b.setBook_price(rs.getFloat("book_price")); b.setBook_type(rs.getString("book_type")); //将对象添加到集合中 blist.add(b); } return blist; } }); //以下为查询原生态代码 } }
BookDaoTest.java 使用Junit测试
package com.zking.pagination.dao;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.zking.pagination.entity.Book;
import com.zking.pagination.util.PageBean;
import com.zking.pagination.util.PinYinUtil;
public class BookDaoTest {
Book book = null;
BookDao bd = new BookDao();
@Before
public void setUp() throws Exception {
//初始化一次
book = new Book();
//System.out.println("setUp");
}
@After
public void tearDown() throws Exception {
//System.out.println("tearDown");
}
@Test
public void testAddBook() {
for (int i = 0; i < 64; i++) {
book = new Book();
book.setBook_name("红楼梦第"+(i+1)+"章");
book.setBook_name_pinyin(PinYinUtil.toPinyin("红楼梦第"+(i+1)+"章").toLowerCase());
book.setBook_price(128f);
book.setBook_type("文学");
//调用dao类添加方法
bd.addBook(book);
}
//System.out.println("testAddBook");
}
@Test
public void testQueryBookPager() {
//模糊查询
book.setBook_name("2");
PageBean pageBean = new PageBean();
pageBean.setPage(2);//第二页
pageBean.setRows(8);//每页条数
//pageBean.setPageination(false);//不分页
//调用dao类查询方法
List books = bd.queryBookPager(book,pageBean);
System.out.println("总记录数:"+pageBean.getTotal());
books.forEach(System.out::println);
}
}
BookServlet.java
package com.zking.pagination.action;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zking.pagination.dao.BookDao;
import com.zking.pagination.entity.Book;
import com.zking.pagination.util.PageBean;
public class BookServlet extends HttpServlet {
@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 {
//获取请求查询参数
String bookname = req.getParameter("bookname");
//实例化BookDao
BookDao bd = new BookDao();
//实例化Book
Book book = new Book();
book.setBook_name(bookname);
//创建PageBean
PageBean pageBean = new PageBean();
//必须在查询之前完成请求参数赋值
pageBean.setRequest(req);
//实现书本查询
List books = bd.queryBookPager(book,pageBean);
//将查询的结果books保存到request作用域中
req.setAttribute("books", books);
//将pageBean对象存入到request作用域中
req.setAttribute("pageBean", pageBean);
//转发到指定页面并显示查询结果
req.getRequestDispatcher("/bookList.jsp").forward(req, resp);;
}
}
配置web.xml
pagination encodingFilter com.zking.pagination.util.EncodingFilter encodingFilter /* BookServlet com.zking.pagination.action.BookServlet BookServlet /BookServlet.action
z标签:是我们的分页标签它还有一个主要的类-----PaginationTag助手类,是整个分页的灵魂所在。
package com.zking.pagination.tag;
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.isPageination())
return "";
else {
StringBuilder sb=new StringBuilder();
//TODO
sb.append("");
//拼接Form表单
sb.append("");
//拼接共几页/第几页
sb.append("[第"+pageBean.getPage()+"页/共"+pageBean.getMaxPager()+"页]");
//拼接首页、上一页、下一页、末页
if(pageBean.getPage()==1)
sb.append("首页 上一页 ");
else {
sb.append("首页 ");
sb.append("上一页 ");
}
if(pageBean.getPage()==pageBean.getMaxPager())
sb.append("下一页 末页 ");
else {
sb.append("下一页 ");
sb.append("末页 ");
}
//拼接跳转页码
sb.append("");
sb.append("");
//拼接javascript跳转方法
sb.append("");
sb.append("");
return sb.toString();
}
}
public PageBean getPageBean() {
return pageBean;
}
public void setPageBean(PageBean pageBean) {
this.pageBean = pageBean;
}
}
启动Tomcat
bookList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="/zking" prefix="z" %>
Insert title here
| 书本编号 | 书本名称 | 书本拼音 | 书本价格 | 书本类型 |
|---|---|---|---|---|
| ${b.book_id } | ${b.book_name } | ${b.book_name_pinyin } | ${b.book_price } | ${b.book_type } |
效果图:



