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">首页</a>
    		<a href="${pageContext.request.contextPath}/${page.url}&num=${page.prePageNum}">上一页</a>
    		<%--显示的页码,使用forEach遍历显示的页面 --%>
    		<c:forEach begin="${page.startPage}" end="${page.endPage}" var="pagenum">
    			<a href="${pageContext.request.contextPath}/${page.url}&num=${pagenum}">${pagenum}</a>
    		</c:forEach>
    		
    		<a href="${pageContext.request.contextPath}/${page.url}&num=${page.nextPageNum}">下一页</a>
    		<a href="${pageContext.request.contextPath}/${page.url}&num=${page.totalPageNum}">末页</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="+pagenum;
    			}
    		</script>
    	</div>
    	<%--分页显示的结束--%>

因为将我们所有需要的数据都封装在了pageModel中,pageModel对象又在request域中,所以在jsp页面中,我们只需要拿到我们所需要的数据,进行显示即可,构造导航图需要注意的有一点,逻辑要搞清楚,想要显示什么不想显示什么,全屏自己控制了,只需要记得一点,在请求Servlet时,需要把请求的页码交给服务器。不然服务器不知道你要获得第几页的数据。

总结
其实分页也不太难,一个难点就是javaBean的构建,只要弄清楚pageModel里面需要哪些属性,各种属性的作用是什么,就会很清晰了。

  • 7
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值