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里面需要哪些属性,各种属性的作用是什么,就会很清晰了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java web velocity分页宏示例

    复制代码 代码如下: #macro(pager $url $pager)<ul class="pagination"> #set($FRONT_LEN = 4) #set($BEHIND_LEN = 5) #set($PAGER_LEN = 10) #set($PAGER_CENTER = $!{pager.pageNum} - $!{BEHIND_LEN}) <li #if($!{pager.currentPage} == 1) class="disabl

  • Java Web中常用的分页组件(Java端实现)

     前言 好久没写Web程序了,这一段时间看了看原来师弟们做的一些程序,感觉还是有很多不足,一个比较典型的例子就是分页查询的实现,正好借着这个机会简单记录一下. 分析 使用场景 "分页"在Web程序里非常常见,比如我们在页面上经常要展示一些列表信息,通常情况下,如果数据过多,我们在一屏上难以罗列出所有的记录,而且很多时候我们可能只是看看比较Top的一些记录,因此,在这种情况下使用"分页"查询只展示部分数据是比较合适的. 实现原理 从数据库角度上来说,分页查询实现的难度

  • JavaWeb中的简单分页完整代码(推荐)

    这次主要是讲解一下通过登录后对得到的数据进行分页,首先我们新建一个登录页面login.jsp,因为我们主要学习一下分页,所以登录验证的部分不再阐述,主要代码如下: <form action="pageServlet"> 用户名:<input type="text" name="username"><br> 密 码:<input type="text" name="passwo

  • JavaWeb 简单分页实现代码

    JavaWeb 简单分页的实现: 这次主要是讲解一下通过登录后对得到的数据进行分页,首先我们新建一个登录页面login.jsp,因为我们主要学习一下分页,所以登录验证的部分不再阐述,主要代码如下: <form action="pageServlet"> 用户名:<input type="text" name="username"><br> 密 码:<input type="text"

  • JavaWeb分页的实现代码实例

    这篇文章主要介绍了JavaWeb分页的实现代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 分页的分类 分页的实现分为真分页和假分页两种. 1.真分页(物理分页): 实现原理: SELECT * FROM xxx [WHERE...] LIMIT ?, 10; 第一个参数是开始数据的索引位置 10是要查询多少条数据,即每页显示的条数 优点: 不会造成内存溢出 缺点: 翻页的速度比较慢 2.假分页(逻辑分页): 实现原理: 一次性将所有的数

  • javaweb分页原理详解

    本文实例为大家分享了javaweb分页原理的具体实现代码,供大家参考,具体内容如下 public class Page { private int currentPage; private int totalPage; private int count; private int PageSize; private List<Product> list; private String category; } servlet: package com.learning.web.servlet;

  • java web实现分页查询实例方法

    Javaweb分页技术实现 分页技术就是通过SQL语句(如下)来获取数据,具体实现看下面代码 //分页查询语句 select * from 表名 where limit page , count; 和 //获取表中的总数据,确定页数 select count(*) from 表名; 不说废话直接上代码 前端代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title&

  • 举例详解用Java实现web分页功能的方法

    分页问题是一个非常普遍的问题,开发者几乎都会遇到,这里不讨论具体如何分页,说明一下Web方式下分页的原理.首先是查询获得一个结果集(表现为查询数据库获得的结果),如果结果比较多我们一般都不会一下显示所有的数据,那么就会用分页的方式来显示某些数据(比如20条).因为Http的无状态性,每一次提交都是当作一个新的请求来处理,即使是换页,上一次的结果对下一次是没有影响的. 这里总结三种实现分页的方式,不知道还有没有别的! 1.每次取查询结果的所有数据,然后根据页码显示指定的纪录. 2.根据页面只取一页

  • Java Web 简单的分页显示实例代码

    本文通过两个方法:(1)计算总的页数. (2)查询指定页数据,实现简单的分页效果. 思路:首先得在 DAO 对象中提供分页查询的方法,在控制层调用该方法查到指定页的数据,在表示层通过 EL 表达式和 JSTL 将该页数据显示出来. 先给大家展示下效果图: 题外话:该分页显示是用 "表示层-控制层-DAO层-数据库"的设计思想实现的,有什么需要改进的地方大家提出来,共同学习进步.废话不多说了,开始进入主题,详细步骤如下所示: 1.DAO层-数据库 JDBCUtils 类用于打开和关闭数据

  • java web手写实现分页功能

    现在很多流行的框架,都可以很快的把分页效果做出来,但是作为一名程序员你必须得知道手写分页的流程: 场景效果: 一.分页的思路 首先我们得知道写分页代码的思路,保持思路清晰,才能行云流水的去写代码,其实不管是在写什么代码,思路,思想特别重要,先想好再动手,就会事半功倍! 先来分析SQL语句实现 Select * from product limit 0 ,5 Select * from product limit 5 ,5 Select * from product limit 10 ,5 Sel

  • Java实现手写线程池的示例代码

    目录 前言 线程池给我们提供的功能 工具介绍 Worker设计 线程池设计 总结 前言 在我们的日常的编程当中,并发是始终离不开的主题,而在并发多线程当中,线程池又是一个不可规避的问题.多线程可以提高我们并发程序的效率,可以让我们不去频繁的申请和释放线程,这是一个很大的花销,而在线程池当中就不需要去频繁的申请线程,他的主要原理是申请完线程之后并不中断,而是不断的去队列当中领取任务,然后执行,反复这样的操作.在本篇文章当中我们主要是介绍线程池的原理,因此我们会自己写一个非常非常简单的线程池,主要帮

  • Java实现手写一个线程池的示例代码

    目录 概述 线程池框架设计 代码实现 阻塞队列的实现 线程池消费端实现 获取任务超时设计 拒绝策略设计 概述 线程池技术想必大家都不陌生把,相信在平时的工作中没有少用,而且这也是面试频率非常高的一个知识点,那么大家知道它的实现原理和细节吗?如果直接去看jdk源码的话,可能有一定的难度,那么我们可以先通过手写一个简单的线程池框架,去掌握线程池的基本原理后,再去看jdk的线程池源码就会相对容易,而且不容易忘记. 线程池框架设计 我们都知道,线程资源的创建和销毁并不是没有代价的,甚至开销是非常高的.同

  • python实现基于SVM手写数字识别功能

    本文实例为大家分享了SVM手写数字识别功能的具体代码,供大家参考,具体内容如下 1.SVM手写数字识别 识别步骤: (1)样本图像的准备. (2)图像尺寸标准化:将图像大小都标准化为8*8大小. (3)读取未知样本图像,提取图像特征,生成图像特征组. (4)将未知测试样本图像特征组送入SVM进行测试,将测试的结果输出. 识别代码: #!/usr/bin/env python import numpy as np import mlpy import cv2 print 'loading ...'

  • Python使用gluon/mxnet模块实现的mnist手写数字识别功能完整示例

    本文实例讲述了Python使用gluon/mxnet模块实现的mnist手写数字识别功能.分享给大家供大家参考,具体如下: import gluonbook as gb from mxnet import autograd,nd,init,gluon from mxnet.gluon import loss as gloss,data as gdata,nn,utils as gutils import mxnet as mx net = nn.Sequential() with net.nam

  • java简单手写版本实现时间轮算法

    时间轮 关于时间轮的介绍,网上有很多,这里就不重复了 核心思想 一个环形数组存储时间轮的所有槽(看你的手表),每个槽对应当前时间轮的最小精度 超过当前时间轮最大表示范围的会被丢到上层时间轮,上层时间轮的最小精度即为下层时间轮能表达的最大时间(时分秒概念) 每个槽对应一个环形链表存储该时间应该被执行的任务 需要一个线程去驱动指针运转,获取到期任务 以下给出java 简单手写版本实现 代码实现 时间轮主数据结构 /** * @author apdoer * @version 1.0 * @date

  • java实现手写一个简单版的线程池

    有些人可能对线程池比较陌生,并且更不熟悉线程池的工作原理.所以他们在使用线程的时候,多数情况下都是new Thread来实现多线程.但是,往往良好的多线程设计大多都是使用线程池来实现的. 为什么要使用线程 降低资源的消耗.降低线程创建和销毁的资源消耗.提高响应速度:线程的创建时间为T1,执行时间T2,销毁时间T3,免去T1和T3的时间提高线程的可管理性 下图所示为线程池的实现原理:调用方不断向线程池中提交任务:线程池中有一组线程,不断地从队列中取任务,这是一个典型的生产者-消费者模型. 要实现一

  • java 百度手写文字识别接口配置代码

    代码如下所示: package org.fh.util; import org.json.JSONObject; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import java.util.Map; /** * 说明:获取文字识别token类 * 作者:

  • Java 通过手写分布式雪花SnowFlake生成ID方法详解

    目录 SnowFlake算法 SnowFlake优点: SnowFlake算法 SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 分为四段: 第一段: 1位为未使用,永远固定为0. (因为二进制中最高位是符号位,1表示负数,0表示正数.生成的id一般都是用正整数,所以最高位固定为0 ) 第二段: 41位为毫秒级时间(41位的长度可以使用69年) 第三段: 10位为workerId(10位的长度最多支持部署1024个节点) (这里的10位又分为两部分,第一部分5位表

随机推荐