java web手写实现分页功能
作者:yechengchao 发布时间:2022-02-04 02:23:15
现在很多流行的框架,都可以很快的把分页效果做出来,但是作为一名程序员你必须得知道手写分页的流程:
场景效果:
一、分页的思路
首先我们得知道写分页代码的思路,保持思路清晰,才能行云流水的去写代码,其实不管是在写什么代码,思路,思想特别重要,先想好再动手,就会事半功倍!
先来分析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里面需要哪些属性,各种属性的作用是什么,就会很清晰了。
来源:https://blog.csdn.net/qq_41097354/article/details/90139948


猜你喜欢
- 本文实例为大家分享了MVPXlistView上拉下拉展示的具体代码,供大家参考,具体内容如下抽基类package com.gs.gg.day
- using System;using System.Collections;using System.Windows.Forms;names
- 本文实例为大家分享了C#添加Windows服务的具体方法,供大家参考,具体内容如下源码下载地址:http://xiazai.jb51.net
- 之前看过一句话,说的特别好。有人问阅读源码有什么用?学习别人实现某个功能的设计思路,提高自己的编程水平。是的,大家都实现一个功能,不同的人有
- & 按位运算符,逻辑运算符&& 逻辑运算符相同点:只要有一端为假,则语句不成立假设有三个参数int x = 1;in
- 本文实例讲述了C#中Memcached缓存的用法,分享给大家供大家参考。具体方法如下:ICacheStrategy.cs文件如下:publi
- 背景现行的文本编辑器大多都具备文本查询的能力,但是并不能直观的告诉用户两段文字的细微差异,所以对比工具在某种情况下,就起到了很便捷的效率。关
- 内部类1. 内部类简介(1) 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。(2) 内部类成员可以
- 前一段时间遇到一个问题,是关于读取项目中文件资源的问题。我是一个maven工程 我把一张照片放到resource下面,然后在本地读取的时候可
- 首先我先声明一点,本文单纯就是技术探讨,要从实际应用中来说的话,我并不建议这样去玩分布式事务、也不建议这样去玩多数据源,毕竟分布式事务主要还
- 用Stream解决两层List属性求和假设一个人有很多个银行账户,每个银行账户中存有不同金额的存款,那么我们如何用Stream求一组人的所有
- 1、什么是ThreadLocal变量ThreadLoal 变量,线程局部变量,同一个 ThreadLocal 所包含的对象,在不同的 Thr
- Redis不仅可作为缓存服务器,还可以用作消息队列。它的列表类型天生支持用作消息队列。如下图所示:由于Redis的列表是使用双向链表实现的,
- 在java中常常会遇到这样一个问题,在实际应用中,总会碰到对List排序并过滤重复的问题,如果List中放的只是简单的String类型过滤s
- 初步计划:或许由于个人原因,排球计分系统在假期就完成了,一直未写博客,就这样一直在推就是不想写,在加上过完年就工作了,可能刚实习工作比较紧所
- 一、什么是Java事务通常的观念认为,事务仅与数据库相关。
- 本文实例讲述了Android TextView跑马灯效果实现方法。分享给大家供大家参考,具体如下:public class MyTextVi
- 排列组合的概念排列:从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排成一列,叫做从n个元素中取出m个元素的一个排列(Arrangem
- 在没讲.net如何随机生成汉字之前先给大家讲下汉字编码组成及原理。1、汉字编码原理到底怎么办到随机生成汉字的呢?汉字从哪里来的呢?是不是有个
- TCP实现TCP协议需要在双方之间建立连接,通过输入输出流来进行数据的交换,建立需要通过三次握手,断开需要四次挥手,保证了数据的完整性,但传