java web手写实现分页功能
现在很多流行的框架,都可以很快的把分页效果做出来,但是作为一名程序员你必须得知道手写分页的流程:
场景效果:
一、分页的思路
首先我们得知道写分页代码的思路,保持思路清晰,才能行云流水的去写代码,其实不管是在写什么代码,思路,思想特别重要,先想好再动手,就会事半功倍!
先来分析SQL语句实现
Select * from product limit 0 ,5 Select * from product limit 5 ,5 Select * from product limit 10 ,5 Select * from product limit 15 ,5
#当前页 起始值 每页数据大小
1 0 5
2 5 5
3 10 5
4 15 5
结论:
(1)(当前页-1)*(每页数量)=起始值
(2)要想实现分页,向服务端发起请求的时候,必须传递当前页。
二、创建PageBean存放数据
这时候我们需要封装一个包装类,来封装我们的分页数据
package cn.itcast.store.domain; import java.util.List; /** * 存放分页相关的数据 * * @author yechengchao */ public class PageModel { //基本属性 /**当前页数,由用户指定 */ private int currentPageNum; /**每页显示的条数,可以由用户指定每页显示多少 */ private int pageSize =5; /**总记录条数,数据库查出来的 */ private int totalRecords; /**总页数,计算出来的 */ private int totalPageNum; /**每页开始记录的索引,计算出来的 (当前页-1)*(每页数量)=起始值 */ private int startIndex; /**上一页 */ private int prePageNum; /**下一页 */ private int nextPageNum; /**已经分好页的结果集,存放我们查出来的结果集*/ private List list; /**扩展属性 一共每页显示9个页码按钮*/ /**开始页码*/ private int startPage; /**结束页码*/ private int endPage; /**完善属性*/ private String url; /**要想使用我的分页,必须给我两个参数。一个是要看哪一页,另一个是总记录条数*/ public PageModel(int currentPageNum,int totalRecords,int pageSize){ this.currentPageNum = currentPageNum; this.totalRecords = totalRecords; this.pageSize=pageSize; //计算查询记录的开始索引 startIndex = (currentPageNum-1)*pageSize; //计算总页数 totalPageNum = totalRecords%pageSize==0?(totalRecords/pageSize):(totalRecords/pageSize+1); //5 startPage = currentPageNum - 4; //结束页码 endPage = currentPageNum + 4; //看看总页数够不够9页 if(totalPageNum>9){ //超过了9页 if(startPage < 1){ startPage = 1; endPage = startPage+8; } if(endPage>totalPageNum){ endPage = totalPageNum; startPage = endPage-8; } }else{ //不够9页 startPage = 1; endPage = totalPageNum; } } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public int getStartPage() { return startPage; } public void setStartPage(int startPage) { this.startPage = startPage; } public int getEndPage() { return endPage; } public void setEndPage(int endPage) { this.endPage = endPage; } public int getPrePageNum() { prePageNum = currentPageNum-1; if(prePageNum<1){ prePageNum = 1; } return prePageNum; } public int getNextPageNum() { nextPageNum = currentPageNum+1; if(nextPageNum>totalPageNum){ nextPageNum = totalPageNum; } return nextPageNum; } public int getCurrentPageNum() { return currentPageNum; } public void setCurrentPageNum(int currentPageNum) { this.currentPageNum = currentPageNum; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getTotalRecords() { return totalRecords; } public void setTotalRecords(int totalRecords) { this.totalRecords = totalRecords; } public int getTotalPageNum() { return totalPageNum; } public void setTotalPageNum(int totalPageNum) { this.totalPageNum = totalPageNum; } public int getStartIndex() { return startIndex; } public void setStartIndex(int startIndex) { this.startIndex = startIndex; } public void setPrePageNum(int prePageNum) { this.prePageNum = prePageNum; } public void setNextPageNum(int nextPageNum) { this.nextPageNum = nextPageNum; } public List getList() { return list; } public void setList(List list) { this.list = list; } }
三、在servlet编写控制代码
首先用户发送请求,带上当前页数,在这表调用业务层的代码,把以分页的形式查询商品,再把商品查询出来之后赋值给我们创建的pageModel对象,这时候把这个对象传到前端页面,就可以把值取出来,实现分页。
public String findProductByCidWithPage(HttpServletRequest request, HttpServletResponse response) throws Exception { //获取cid,num String cid=request.getParameter("cid"); int curNum=Integer.parseInt(request.getParameter("num")); //调用业务层的功能:以分页的形式查询当前页类别下商品信息 //返回PageModel对象(1当前页商品信息2分页3 url) ProductService productService=new ProductServiceImp(); PageModel pm=productService.findProductByCidWithPage(cid,curNum); //将PageModel对象放入request request.setAttribute("page", pm); //转发到/jsp/product_list.jsp return "/jsp/product_list.jsp"; }
四、业务层service编写业务逻辑代码
当调用业务层的业务逻辑的时候,在这边我们是通过Dao层把我们要查询的商品查询出来用一个list接收,再传给pageModel的属性list,这时候就把整个pageModel对象传回去,这边主要是调用Dao层查询和 关联集合,关联URL。
public PageModel findProductByCidWithPage(String cid, int curNum) throws Exception { //1 创建pageModel对象 目的:计算分页参数 //统计当前分类下商品的个数 select count(*) from product where cid=? int totalRecords=productDao.findtotalRecords(cid); PageModel pageModel=new PageModel(curNum, totalRecords, 12); //2.关联集合 select * form product where cid=? limit ?,? List list=productDao.findProductByCidWithPage(cid,pageModel.getStartIndex(),pageModel.getPageSize()); pageModel.setList(list); //3.关联url pageModel.setUrl("ProductServlet?method=findProductByCidWithPage&cid="+cid); return pageModel; }
五、Dao层操作数据库
为什么我们要在最开始分析sql语句,最根源就是在这边查询数据库,我们需要把起始页和分页大小传进去。
public List findProductByCidWithPage(String cid, int startIndex, int pageSize) throws Exception { String sql="select * from product where cid=? limit ?,?"; QueryRunner qr=new QueryRunner(JDBCUtils.getDataSource()); return qr.query(sql, new BeanListHandler<Product>(Product.class),cid,startIndex,pageSize); }
六、前端页面,显示分页
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%--分页显示的开始 --%> <div style="text-align:center"> 共${page.totalPageNum}页/第${page.currentPageNum}页 <a href="${pageContext.request.contextPath}/${page.url}&num=1" rel="external nofollow" >首页</a> <a href="${pageContext.request.contextPath}/${page.url}&num=${page.prePageNum}" rel="external nofollow" >上一页</a> <%--显示的页码,使用forEach遍历显示的页面 --%> <c:forEach begin="${page.startPage}" end="${page.endPage}" var="pagenum"> <a href="${pageContext.request.contextPath}/${page.url}&num=${pagenum}" rel="external nofollow" >${pagenum}</a> </c:forEach> <a href="${pageContext.request.contextPath}/${page.url}&num=${page.nextPageNum}" rel="external nofollow" >下一页</a> <a href="${pageContext.request.contextPath}/${page.url}&num=${page.totalPageNum}" rel="external nofollow" >末页</a> <input type="text" id="pagenum" name="pagenum" size="1"/><input type="button" value="前往" onclick="jump()" /> <script type="text/javascript"> function jump(){ var totalpage = ${page.totalPageNum}; var pagenum = document.getElementById("pagenum").value; //判断输入的是一个数字 var reg =/^[1-9][0-9]{0,1}$/; if(!reg.test(pagenum)){ //不是一个有效数字 alert("请输入符合规定的数字"); return ; } //判断输入的数字不能大于总页数 if(parseInt(pagenum)>parseInt(totalpage)){ //超过了总页数 alert("不能大于总页数"); return; } //转向分页显示的Servlet window.location.href="${pageContext.request.contextPath}/${page.url}&num=" rel="external nofollow" +pagenum; } </script> </div> <%--分页显示的结束--%>
因为将我们所有需要的数据都封装在了pageModel中,pageModel对象又在request域中,所以在jsp页面中,我们只需要拿到我们所需要的数据,进行显示即可,构造导航图需要注意的有一点,逻辑要搞清楚,想要显示什么不想显示什么,全屏自己控制了,只需要记得一点,在请求Servlet时,需要把请求的页码交给服务器。不然服务器不知道你要获得第几页的数据。
总结
其实分页也不太难,一个难点就是javaBean的构建,只要弄清楚pageModel里面需要哪些属性,各种属性的作用是什么,就会很清晰了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。