JSP通用分页

2023-11-18

 通用分页核心思路:将上一次查询请求再发一次,只不过页码变了
 实现步骤:
   1)先查询全部数据
    baseDao<T>
   2)通用分页实现
    pagebean


1. PageBean
   分页三要素 
   page=1        页码        视图层传递过来
   rows=10         页大小      视图层传递过来
   total=0       总记录数    后台查出来

 pagination=true  是否分页    视图层传递过来

   getStartIndex()        基于MySql数据库分页,获取分页开始标记
  (page-1)*rows

  url         请求路径    视图层传递过来 
   map           参数集合    视图层传递过来
   setRequest(HttpServletRequest req)  设置请求参数

   getMaxPager()        获取最大页码
   getProviousPager()   获取上一页
   getNextPager()       获取下一页

2. 后台
  2.1 entity
  2.2 dao
      BaseDao<T>
 1)匿名内部接口
 2)分页查询方法,接口方法传参
  3)二次查询的条件要一致

3.视图层
   PageTag

   点击分页按钮,将上一次的请求再发一次
   注意:不能将分页表单嵌套到其它表单中,否则不能提交表单!

pageTag代码

package com.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.util.PageBean;

public class PageTag extends BodyTagSupport{

	private PageBean pageBean;//包含了所有分页相关的元素
	
	public int doStartTag() throws JspException {
		JspWriter out = pageContext.getOut();
		try {
			out.print(toHTML());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return super.doStartTag();
	}
	private String toHTML() {
		StringBuffer sb=new StringBuffer();
		
		//隐藏的form表单---上一次请求下一次重新发送的关键
		sb.append("<form action='"+pageBean.getUrl()+"' id='pageBeanForm' method='post'>");
		sb.append("<input type='hidden' name='page'>");
		Map<String, String[]> map = pageBean.getMap();//上一次请求的参数
		
		if(map!=null&&map.size()>0) {
			Set<Entry<String, String[]>> set = map.entrySet();
			for (Entry<String, String[]> s : set) {
				//参数名
				String key = s.getKey();
				//参数值
				String[] value = s.getValue();
				for (String v : value) {
					//上一次请求的参数,再一次拼成了新的form表单
					//注意:page参数每次都会提交,我们需避免
					if(!"page".equals(key)) {
					sb.append(" <input type='hidden' name='"+key+"' value='"+v+"'>");
				}
			  }
			}
		}
		sb.append("</form>");
		sb.append("<ul class='pagination justify-content-center'>");
		sb.append(" <li class='page-item "+(pageBean.getPage()==1?"disable":"")+"'><a class='page-link' href='javascript:gotoPage(1)'>首页〉</a></li>");
		sb.append(" <li class='page-item "+(pageBean.getPage()==1?"disable":"")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.previousPage()+")'>&lt;</a></li>");
//		sb.append(" <li class='page-item'><a class='page-link' href='#'>1</a></li>");
//		sb.append(" <li class='page-item'><a class='page-link' href='#'>2</a></li>");
		sb.append(" <li class='page-item active'><a class='page-link' href='javascript:gotoPage("+pageBean.getPage()+")'>"+pageBean.getPage()+"</a></li>");
		sb.append(" <li class='page-item "+(pageBean.getPage()==pageBean.maxPage()?"disable":"")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.nextPage()+")'>&gt;</a></li>");
		sb.append(" <li class='page-item "+(pageBean.getPage()==pageBean.maxPage()?"disable":"")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.maxPage()+")'>尾页〉</a></li>");
		sb.append(" <li class='page-item go-input'><b>到第</b><input class='page-link' type='text' id='skipPage' name='' /><b>页/b></li>");
		sb.append(" <li class='page-item go'><a class='page-link' href='javascript:skipPage()'>确定</a></li>");
		sb.append(" <li class='page-item'><b>共"+pageBean.getTotal()+"条</b></li>");
		sb.append("</ul>");
		
		sb.append("<script type='text/javascript'>");
		sb.append("       function gotoPage(page) {");
		sb.append("             document.getElementById('pageBeanForm').page.value = page;");
		sb.append("             document.getElementById('pageBeanForm').submit();");
		sb.append("          }");
		sb.append("");
		sb.append("       function skipPage() {");
		sb.append("            var page = document.getElementById('skipPage').value;");
		sb.append("            if (!page || isNaN(page) || parseInt(page) < 1 || parseInt(page) > "+pageBean.maxPage()+") {");
		sb.append("                    alert('请输入1-"+pageBean.maxPage()+"的数字');");
		sb.append("                     return;");
		sb.append("         }");
		sb.append("   gotoPage(page);");
		sb.append(" }");
		sb.append("</script>");
		return sb.toString();
	}
	@Override
	public int doEndTag() throws JspException {
		return super.doEndTag();
	}
}

bookDao代码

package com.dao;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
 
import com.entity.Book;
import com.util.DBAccess;
import com.util.PageBean;
 
public class BookDao extends BaseDao<Book>{
/**
 * 未继承时的方法
 * @param book
 * @return
 * @throws Exception
 */
	public List<Book> getAll(Book  book) throws Exception{
		List<Book> list=new ArrayList<Book>();
		String sql="select * from t_mvc_book where 1=1";
		//书籍名称
		String bname = book.getBname();
		if(com.util.StringUtils.isNotBlank(bname)) {
			sql+=" and bname like %"+bname+"%";
		}
		Connection con=DBAccess.getConnection();
		PreparedStatement ps = con.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		while(rs.next()) {
			Book b=new Book();
			b.setBid(rs.getInt("bid"));
			b.setBname(rs.getString("bname"));
			b.setPrice(rs.getDouble("price"));
			list.add(b);
		}
		return list;
	}
	
	
	
/**
 * 继承父类后的方法
 * @param book
 * @return
 * @throws Exception
 */
	public List<Book> getAll2(Book  book) throws Exception{
		String sql="select * from t_mvc_book where 1=1";
		//书籍名称
		String bname = book.getBname();
		if(com.util.StringUtils.isNotBlank(bname)) {
			sql+=" and bname like %"+bname+"%";
		}
		
		return super.getAll(sql, Book.class);
	}
	
	/**
	 * 实现分页
	 * @param book
	 * @param pageBean
	 * @return
	 * @throws Exception
	 */
	public List<Book> getAll3(Book  book,PageBean pageBean) throws Exception{
		String sql="select * from t_mvc_book where 1=1";
		//书籍名称
		String bname = book.getBname();
		if(com.util.StringUtils.isNotBlank(bname)) {
			sql+=" and bname like %"+bname+"%";
		}
		
		return super.pages(sql, Book.class, pageBean);
	}
}

pageBean代码

package com.util;
 
import java.util.HashMap;
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
 
/**
 * 鍒嗛〉宸ュ叿绫�
 *
 */
public class PageBean {
 
	private int page = 1;// 起始页
 
	private int rows = 10;// 每页展示条数
 
	private int total = 0;// 总条数
 
	private boolean pagination = true;// 是否分页
 
	private String url;//保存上一次请求的url
	
	private Map<String, String []> map=new HashMap<>();
	
	public void setRequest(HttpServletRequest req) {
		this.setUrl(req.getRequestURI().toString());
		this.setMap(req.getParameterMap());
		this.setPagination(req.getParameter("pagination"));
		this.setRows(req.getParameter("rows"));
		this.setPage(req.getParameter("page"));
	}
	
	private void setPage(String page) {
		if(StringUtils.isNotBlank(page)) {
			this.setPage(Integer.parseInt(page));
		}
		
	}
	private void setRows(String rows) {
		if(StringUtils.isNotBlank(rows)) {
			this.setRows(Integer.valueOf(rows));
		
		}
	}
 
	public void setPagination(String pagination) {
		if(StringUtils.isNotBlank(pagination)) {
			this.setPagination(!"false".equals(pagination));
		}
		
	}
 
	public PageBean() {
		super();
	}
 
	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 void setTotal(String total) {
		this.total = Integer.parseInt(total);
	}
 
	public boolean isPagination() {
		return pagination;
	}
 
	public void setPagination(boolean pagination) {
		this.pagination = pagination;
	}
	
 
	public String getUrl() {
		return url;
	}
 
	public void setUrl(String url) {
		this.url = url;
	}
 
	public Map<String, String[]> getMap() {
		return map;
	}
 
	public void setMap(Map<String, String[]> map) {
		this.map = map;
	}
 
	/**
	 * 鑾峰緱璧峰璁板綍鐨勪笅鏍�
	 * 
	 * @return
	 */
	public int getStartIndex() {
		return (this.page - 1) * this.rows;
	}
/**
 * 最大页码
 * @return
 */
	public int maxPage() {
		return this.total%this.rows==0?this.total/this.rows:this.total/this.rows+1;
	}
	/**
	 * 下一页
	 * @return
	 */
	public int nextPage() {
		return this.page<maxPage()?this.page+1:this.page;
	}
	/**
	 * 上一页
	 * @return
	 */
	public int previousPage() {
		return this.page<1 ? 1:this.page-1;
	}
	
	@Override
	public String toString() {
		return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
	}
 
}

servlet代码

package com.web;
 
import java.io.IOException;
import java.util.List;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import com.dao.BookDao;
import com.entity.Book;
import com.util.PageBean;
@WebServlet("/index.do")
public class BookServlet extends HttpServlet {
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Book b=new Book();
		BookDao bd=new BookDao();
		b.setBname(req.getParameter("bname"));
		PageBean p=new PageBean();
		p.setRequest(req);
		try {
			List<Book> all3 = bd.getAll3(b, p);
			req.setAttribute("list3", all3);
			req.setAttribute("pageBase", p);
		} catch (Exception e) {
			e.printStackTrace();
		}
		req.getRequestDispatcher("index.jsp").forward(req, resp);
	}
 
}

jsp界面

<%@taglib prefix="zking" uri="http://java.veryedu.cn"%>    
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    

    <form class="form-inline"
        action="${pageContext.request.contextPath }/book/search" method="post">
        <div class="form-group mb-2">
        <input type="text" class="form-control-plaintext" name="bname" 
                placeholder="请输入书籍名称">
        </div>
        <button type="submit" class="btn btn-primary mb-2">查询</button>
    </form>

    <table class="table table-striped bg-success">
        <thead>
            <tr>
                <th scope="col">书籍ID</th>
                <th scope="col">书籍名</th>
                <th scope="col">价格</th>
            </tr>
        </thead>
        <tbody>
        <c:forEach var="b" items="${books }">
            <tr>
                <td>${b.bid }</td>
                <td>${b.bname }</td>
                <td>${b.price }</td>
            </tr>
            </c:forEach>

        </tbody>
    </table>
    <!-- 这一行代码就相当于前面分页需求前端的几十行代码 -->
    <zking:Page pageBean="${pageBean }"></zking:Page>

要是乱码了,记得用过滤器处理哦
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JSP通用分页 的相关文章

  • 使用 Javascript 防止刷新“跳转”

    我注意到 如果您在一个页面上并且向下滚动了很多 如果您刷新页面 大多数浏览器会将您跳回到您的位置 有什么办法可以防止这种情况发生吗 我研究了两个选项 但在 Webkit Firefox 上都不一致 window scrollTo 0 1 h
  • 如何使用 Fabric js 以编程方式自由绘制?

    使用 Fabric js 构建多人涂鸦 尝试使用 Fabric js 实现多人涂鸦 想法是当 U1 在画布上绘制时 我们将点推送到 RTDB 并在客户端上获取这些点 并以编程方式在两个客户端中绘制笔画 您可以将画布的数据保存在path cr
  • 解析 Angular2 中的 xml 以在视图中呈现

    我是否需要解析 xml 以从 xml 获取数据以在 html 中呈现 我目前正在使用获取本地 xml 文件http get请求并在控制台日志中显示 xml 文件中的所有信息 我认为它只是在读取它 问题是如何在angular2中将xml转换为
  • 我在 firebase.auth.ApplicationVerifier 中遇到问题

    错误发生在signInWithPhoneNumber 的第二个参数中 我无法解决这个问题 我使用了三种方法来发送 otp 验证 otp 和最后用于验证码 methods sendOTP e e preventDefault if this
  • 是否可以告诉 jsdoc 在与源代码分开的文件中查找该代码的文档?

    我希望内联注释尽可能短 因为我的经验是超过 3 或 4 行的注释往往会被掩盖 从而产生很多不必要的 阅读手册行 遗留系统要求我遵守与 jsdoc 兼容的格式来记录代码 如果要正确记录许多不言而喻的事情 则需要明确声明它们 实际上每个标签都可
  • 在 VueJs 中使用上下键自动完成搜索

    除了自动完成搜索之外 我还想添加功能以允许使用 VueJs 按下 向上键功能 我的模板如下所示 div h2 Todos h2 div class autocomplete div div
  • 屏幕上的中心 div 已使用 css3 旋转和缩放

    我有以下 jsfiddle https jsfiddle net quacu0hv https jsfiddle net quacu0hv 我不知道如何使这个 div 居中 事实上 它是旋转的 因此很难将对象真正置于屏幕上的中心 纯CSS到
  • 将数组传递给 include() javascript

    我试图找出一个字符串是否包含存储在数组中的多个字符串 includes 所以我尝试过 let string hello james console log string includes hello james 但它被返回为false 当我
  • 将 viewbag 转换为 javascript 数组

    我想将数据从 ViewBag mytags 获取到 Javascript 数组 但我无法执行此操作 function var sampleTags new Array var array Html Raw Json Encode ViewB
  • 如何为 HTML 验证提供自定义验证错误消息?

    当我使用默认 HTML 验证时 它会显示默认错误消息 这不是我想向客户显示的 我需要自定义消息并为每个验证提供不同的信息 例如最小 最大 类型和要求 例如 该字段为必填项 值不匹配 参考传统的HTML代码
  • 我应该担心“窗口未定义”JSLint 严格模式错误吗?

    这不会在严格模式下通过 JSLint use strict function w w alert w window 来自 jslint com 的错误如下所示 第 4 行第 3 行字符出现问题 window 未定义 window 隐含全局
  • Cloudflare Worker 缓存 API 出现问题

    我现在花了无数的时间尝试让缓存 API 来缓存一个简单的请求 我让它在中间工作过一次 但忘记向缓存键添加一些内容 现在它不再工作了 不用说 cache put 没有指定请求是否实际被缓存的返回值并不完全有帮助 我只能进行反复试验 有人可以给
  • 我将与 ng-include 一起使用什么文件路径?

    我的角度项目的路径是这样的 web server py flask server program app static app js controllers js etc templates index html home html 索引
  • 如何将对象传递给 onclick 事件[重复]

    这个问题在这里已经有答案了 可能的重复 Javascript 循环内的事件处理程序 需要闭包吗 https stackoverflow com questions 341723 event handlers inside a javascr
  • jsx转js后dom未定义错误

    我创建了一个 jsx 文件 如下所示 jsx dom function use strict define jquery react react dom function React ReactDOM var AppView React c
  • 是否可以模拟 isTrusted=true

    我希望在调用 touchStart 事件时能够模拟 isTrusted true 是否有任何库或任何类型的解决方法可以实现这一点 以下是我以编程方式运行 touchStart 时的输出与实际调用 touchStart 时的输出 我正在使用移
  • 什么是 TypeScript?为什么我要用它代替 JavaScript? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 您能描述一下 TypeScript 语言是什么吗 它能做什么 JavaScript 或可用库不能做的事情 这让我有理由考虑它 我最初写
  • CSS 可见性动画不起作用

    我想在 CSS 可见性属性上制作基于关键帧的动画 我最初在 显示 上尝试过 但发现不支持 显示 上的动画 但支持 可见性 这个想法是让矩形的可见性不断切换 我不想使用 jquery 并且想在 CSS 中实现整个它 以下是我的代码 但它没有给
  • 展平数组中的对象

    大家好 我从响应中获取了一系列对象 我需要将所有学生对象展平为简单的学生姓名 但不确定如何进行 任何帮助将不胜感激 数组示例 students id 123456 name Student Name active true students
  • Javascript - 从 AWS s3 存储桶读取镶木地板数据(使用快速压缩)

    In nodeJS 我正在尝试读取镶木地板文件 压缩 snappy 但没有成功 I used https github com ironSource parquetjs https github com ironSource parquet

随机推荐

  • Inno Setup 系列之安装、卸载时调用bat

    需求 想在安装的时候调用install bat 在卸载的时候调用uninstall bat 解决 可以这样写 Inno Setup 的脚本 Setup NOTE The value of AppId uniquely identifies
  • Java中的OOP

    OOP Object Oriented Programming 是面向对象编程 OOP特征分别是封装 继承 多态 1 封装 保护内部的操作不被破坏 2 继承 在原本的基础之上继续进行扩充 3 多态 在一个指定的范围之内进行概念的转换 Jav
  • C++ 重载、覆盖、隐藏

    C 重载 覆盖 隐藏 重载 覆盖和隐藏是C 中容易混淆的概念 作为C 研发人员有必要了解其区别和实现 以下结合概念和源码加以说明 1 重载 重载指同一个类或者范围内 被声明的同名函数其参数数量或者类型不同 使用时根据函数参数列表确定调用哪个
  • 使用ifconfig结合awk提取主机的IP地址方法

    ifconfig是用来配置或者显示网卡信息的工具 可以提供与ip a类似的功能 在CentOS7以后的版本里 ifconfig是默认没有安装的 需要安装net tools工具 我们可以借助ifconfig工具 使用下面简单的脚本来完成主机I
  • 如何使用cd命令

    转自http jingyan baidu com article 8cdccae99f3d46315513cd47 html 以下适用于windows环境 cd就是change directory的缩写 即改变目录 讲cd命令之前 先来看看
  • 【Linux】Systemd+rc.local设置开机自启动

    1 问题描述 ubuntu18 04不再使用 inited 管理系统 改用 systemd 启动时 默认不再使用调用 etc rc local 如果想开机时调用 etc rc local 需要修改systemd的配置 2 解决方法 2 1
  • 任意进制之间的转换(C++实现)

    任意进制之间的转换 C 实现 题目描述 输入格式 第一行输入两个整数 n 和 m 2 lt n m lt 16 n 代表的是第二行输入的数的进制 m 代表的是输出的数字的进制 第二行输入一个x 如果有字母 输入大写字母 输出格式 输出一个
  • PCA主成分分析

    PCA主成分分析 优点 降低数据的复杂性 识别最重要的多个特征 缺点 不一定需要 且可能损失有用信息 适用数据类型 数值型数据 PCA背景知识 移动坐标轴 考虑上图中的大量数据点 如果要求我们画出一条直线 这条线要尽可能覆盖这些点 那么最长
  • 在Matlab实现Kmeans算法(每行代码带注释)

    目录 一 前言 二 VQ概述 三 Kmeans算法 K means 的算法步骤为 四 Matlab代码实现过程 五 一点点可选改动 个人看法 参考链接 一 前言 本人对机器学习 人工智能算法方面没什么研究 只是学习过程中恰好碰到了 一开始看
  • 哪款 Linux 才是更好的 CentOS 替代品?

    AlmaLinux 是基于 RHEL 的企业级 Linux 发行版 以下是选择 AlmaLinux 作为 CentOS 替代方案的一些原因 CentOS 将于 2024 年 6 月到期 截至 2022 年 它为世界各地的许多服务器支持 事实
  • idea提示非法字符

    问题 解决方法 将编码格式UTF 8 BOM文件转为普通的UTF 8文件 一 简单方法 在AS右下角 将编码改为GBK 再转为UTF 8 可以解决 二 可以用EditPlus 1 将文件用EditPlus打开 然后选择Document 文件
  • 点积,内积,哈达玛积的区别

    哈达玛积哈达玛积 Hadamard product 是矩阵的一类运算 若A aij 和B bij 是两个同阶矩阵 若cij aij bij 则称矩阵C cij 为A和B的哈达玛积 或称基本积 乘完之后还是矩阵 点积点积在数学中 又称数量积
  • Unity_场景之间的跳转

    跳转场景之前 需要在 File gt Build Settings gt Add Open Scenes 或者 直接把 场景 拖拽进来 跳转场景方法1 已过时 跳转场景方法 public void OnStartGame string Sc
  • PC端地图Hybird应用开发(百度地图API+C#+JavaScript)

    接了一个外包 让我做地图系统 采用C 嵌套JavaScript编程 为Hybird应用 框架内存是基于winform 调用了控件webbrowser webbrowser解释 渲染html文件 JavaScript脚本 地图采用百度地图AP
  • Nginx 502 Bad Gateway 错误的解决方法

    502 bad gateway 的解决方法 通用配置proxy buffer size 4k 设置代理服务器 nginx 保存用户头信息的缓冲区大小 proxy buffers 4 32k proxy buffers缓冲区 网页平均在32k
  • 动态自适应可变加权极限学习机(Dynamic Adaptive Variable Weighted Extreme Learning Machine, DAVW

    动态自适应可变加权极限学习机 Dynamic Adaptive Variable Weighted Extreme Learning Machine DAVW ELM 预测算法附Matlab代码 极限学习机 Extreme Learning
  • C++ 合并链表

    合并2个递增链表 使得合并后仍保持递增顺序 MergeList cpp 合并2个排序的链表 2个递增的排序链表 合并这2个使得新链表中的结点仍是按照递增顺序排列的 include
  • 端口安全、MAC地址漂移、MACsec、流量控制、DHCP snooping

    二 知识点 1 端口安全 实验拓扑1 实验拓扑2 2 mac地址漂移 操作拓扑 3 MACSEC 4 流量抑制和风暴控制 演示拓扑 5 DHCP snooping 实验拓扑 DHCP snooping
  • Cisco switch vulnerability

    Cisco switch SSH Protocol Version 1 Session Key Retrieval https community cisco com t5 security knowledge base guide to
  • JSP通用分页

    通用分页核心思路 将上一次查询请求再发一次 只不过页码变了 实现步骤 1 先查询全部数据 baseDao