Java研学-分页查询

一 分页概述

1 介绍

  将大量数据分段显示,避免一次性加载造成的内存溢出风险

2 真假分页

① 真分页
  一次性查询出所有数据存到内存,翻页从内存中获取数据,性能高但易造成内存溢出
② 假分页
  每次翻页从数据库中查询数据,性能低,但不易造成内存溢出

二 分页设计

1 分页传递参数 – 需用户传入的参数

  currentPage:当前页,跳转到第几页,int类型,设置默认值,比如1

  pageSize:每页最多多少条数据,int类型,设置默认值,比如 5

2 分页展示数据 – 分页依赖数据(分页条)

  beginPage:首页
  prevPage:上一页
  nextPage:下一页
  totalPage:总页数/末页
  totalCount/rows:总条数
  currentPage:当前页
  pageSize:每页显示多少条数据

3 分页展示数据的来源

① 来源于用户传入:
  currentPage:当前页,int类型
  pageSize:每页显示多少条数据,int类型
② 来源于两条SQL查询:
  totalCount/rows:数据总条数,int类型
  data/list:每一页的结果集数据,List类型
③ 来源于程序计算:
  totalPage:总页数/末页,int类型
  prevPage:上一页,int类型
  nextPage:下一页,int类型

4 结果总条数与结果集

  结果总数(totalCount/rows)和结果集(data/list)来源于两条SQL:

// 查询符合条件的结果总数(totalCount/rows)
SELECT COUNT(*)FROM 表名[WHERE 条件]// 第一个?:从哪一个索引的数据开始查询(默认从0开始)
// 第二个?:查询多少条数据
SELECTFROM 表名[WHERE 条件]LIMIT ?,? 

  第二条SQL中的两个参数,第一个取值为(currentPage-1)* pageSize,第二个取值为pageSize,都来源于用户传递的参数

5 总页数与上下翻页

  总页数与上下翻页,来自程序计算

// 优先计算 totalPage 
int totalPage = rows % pagesize == 0 ? rows / pagesize : rows / pagesize +1; 
int prevpage = currentPage -1>=1 ? currentPage - 1:1;
int nextpage = currentPage +1 <= totalpage ? currentPage + 1: totalpage; 

三 分页实现(后台)

1 流程

分页流程

2 数据封装

  为实现流程效果,需将查询回的分页数据封装成一个对象传递给JSP,这样只需要共享一个对象即可

3 封装对象 – PageResult

@Setter
@Getter
public class PageResult<T> {//上一页private  Integer prevPage;//下一页private  Integer nextPage;//总条数private  Integer totalCount;//总页数private Integer totalPage;//当前页码private Integer currentPage;//每页显示条数private Integer pageSize;//查询的集合private List<T> list;/*初始化分页对象有参构造*/public  PageResult(Integer currentPage,Integer pageSize,Integer totalCount,List<T> list){this.currentPage=currentPage;this.pageSize=pageSize;this.totalCount=totalCount;this.list=list;//总页数=总条数/每页显示条数 当求模运算值不等于0的时候总页数加1this.totalPage=(this.totalCount%this.pageSize==0)?(this.totalCount/this.pageSize):(this.totalCount/this.pageSize+1);//上一页this.prevPage=(this.currentPage==1)?(1):(this.currentPage-1);//下一页this.nextPage=(this.currentPage==this.totalPage)?(this.totalPage):(this.currentPage+1);}
}

4 Dao层实现

  为实现分页Dao层需增加两个方法,一个是查询数据总量,一个查询当前页的数据

// 数据总量
int queryCount(int currentPage,int pageSize);
// 结果集
List<Employee> queryPage(int currentPage,int pageSize);

  MyBatis提供的操作方法传入执行SQL的参数只能是1个,此时两个参数需要传递两个分页实参,可以使用Map封装参数,或者使用JavaBean封装参数

5 封装分页参数 – QueryObject

@Setter
@Getter
public class QueryObject {private Integer currentPage=1;private Integer pageSize=3;public int getStart(){return   (currentPage-1)*pageSize;//计算查询的起始索引}
}

6 编辑对应的Dao接口

	// EmployeeDao/*查询总条数*/int queryCount(QueryObject qo);/*分页查询*/List<Employee> queryPage(QueryObject qo);

7 编辑Dao的实现类

	@Overridepublic int queryCount(QueryObject qo) {return sqlSession.selectOne("cn.tj.mapper.EmployeeMapper.queryCount",qo);}@Overridepublic List<Employee> queryPage(QueryObject qo) {return sqlSession.selectList("cn.tj.mapper.EmployeeMapper.queryPage",qo);}

8 编辑对应Mapper文件

	<!--查询总条数--><select id="queryCount" resultType="int">SELECT count(*) from employee</select><!--分页查询--><select id="queryPage" resultType="Employee">SELECT * from employee limit #{start},#{pageSize}</select>

9 业务层实现

  Servlet调用时返回分页查询的结果,返回PageResult对象,形参类型为QueryObject

	// service层接口/*分页查询*/PageResult<Employee> queryByPage(QueryObject qo);// service层实现类/*分页查询*/@Overridepublic PageResult<Employee> queryByPage(QueryObject qo) {//查询总条数int totalCount = employeeDao.queryCount(qo);if(totalCount==0){return new PageResult<>(qo.getCurrentPage(),qo.getPageSize(),0, Collections.emptyList());}//查询分页集合List<Employee> list = employeeDao.queryPage(qo);//创建分页对象PageResult<Employee> pageResult=new PageResult<>(qo.getCurrentPage(),qo.getPageSize(),totalCount,list);return pageResult;}

四 分页实现(前台)

1 流程

  前台主要指Servlet及JSP,Servlet处理请求,调用业务方法,把查询到数据共享到JSP中,展示给用户看。
  浏览器发出分页请求参数(去往第几页/每页多少条数据),在Servlet中接收这些参数,并封装到QueryObject对象,调用Service中分页查询方法(query).
  把得到的分页查询结果对象(PageResult)共享在请求作用域中,跳转到JSP,显示即可。
  修改JSP页面,编写出分页条信息(分页条中的信息来源于PageResult 对象)。

2 EmployeeServlet

// 获取页面传递的分页参数,执行查询,将结果共享到请求作用域,请求转发回到list.jsp页面
@WebServlet("/employee")
public class EmployeeServlet extends HttpServlet {private EmployeeService employeeService=new EmployeeServiceImpl();@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置编码格式req.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");// 登录权限判断 操作员工需要先登录HttpSession session = req.getSession();Users users = (Users) session.getAttribute("USER_IN_SESSION");if (users==null){//如果没有登录,跳转登录页面,给出提示req.setAttribute("msg","请先登录再操作!");req.getRequestDispatcher("/login.jsp").forward(req,resp);return;}//获取请求分发的参数String cmd = req.getParameter("cmd");if ("delete".equals(cmd)){//调用删除delete(req,resp);}else if("input".equals(cmd)){//跳转到增加或修改页面input(req,resp);} else if("saveOrUpdate".equals(cmd)){//保存增加或修改saveOrUpdate(req,resp);}else{//查询所有list(req,resp);}}/*增加修改保存*/private void saveOrUpdate(HttpServletRequest req, HttpServletResponse resp) {//封装员工对象Employee employee=new Employee();/*将参数的获取及封装对象过程抽取成一个方法*/req2employee(req,employee);/*根据请求中是否携带id判断执行增加或者修改操作*/String id = req.getParameter("id");if (StringUtil.hasLength(id)){employee.setId(Long.valueOf(id));//执行修改employeeService.update(employee);}else{//调用dao方法执行增加保存操作employeeService.add(employee);}try {//跳转到查询resp.sendRedirect("/employee");} catch (IOException e) {e.printStackTrace();}}/*封装的获取请求参数的方法*/private void req2employee(HttpServletRequest req, Employee employee) {//获取请求中表单参数String name = req.getParameter("name");//验证输入的表单参数不能为空if (StringUtil.hasLength(name)){//编辑员工姓名employee.setName(name);}String salary = req.getParameter("salary");if (StringUtil.hasLength(salary)){employee.setSalary(Double.valueOf(salary));}}/*跳转到编辑页面*/private void input(HttpServletRequest req, HttpServletResponse resp) {//根据请求中是否携带id判断是增加或者修改操作String id = req.getParameter("id");if (StringUtil.hasLength(id)){//请求中携带了id执行修改//根据id查询员工Employee employee = employeeService.selectOne(Long.valueOf(id));//将查询的员工存储到作用域req.setAttribute("employee",employee);}try {//跳转到WEB-INF下面的页面:input.jspreq.getRequestDispatcher("/WEB-INF/views/employee/input.jsp").forward(req,resp);} catch (Exception e) {e.printStackTrace();}}/*分页查询所有*/private void list(HttpServletRequest req, HttpServletResponse resp) {try {/*客户端如果传入了当前页码和每页显示条数则设置给qo对象,如果没有传入则使用默认值*/String currentPage = req.getParameter("currentPage");String pageSize = req.getParameter("pageSize");QueryObject qo=new QueryObject();if (StringUtil.hasLength(currentPage)){qo.setCurrentPage(Integer.valueOf(currentPage));}if (StringUtil.hasLength(pageSize)){qo.setPageSize(Integer.valueOf(pageSize));}//调用service分页查询的方法PageResult<Employee> pageResult = employeeService.queryByPage(qo);//将查询的结果存储到请求作用域req.setAttribute("pageResult",pageResult);//转发到列表页面req.getRequestDispatcher("/WEB-INF/views/employee/list.jsp").forward(req,resp);} catch (Exception e) {e.printStackTrace();}}/*删除*/private void delete(HttpServletRequest req, HttpServletResponse resp) {try {//获取目标idString id = req.getParameter("id");//调用删除方法int row = employeeService.delete(Long.valueOf(id));//删除完毕跳转到查询resp.sendRedirect("/employee");} catch (IOException e) {e.printStackTrace();}}
}

3 list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入核心标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>员工信息页面</title>
</head>
<body>
<center><h3>员工列表</h3><p>当前登录账号:${sessionScope.USER_IN_SESSION.username}</p><p><%--点击跳转到上传头像的表单页面--%><a href="/headImg.jsp"><%--头像--%><img src="/upload/${sessionScope.USER_IN_SESSION.headImg}" width="100px" height="100px"><p>${sessionScope.USER_IN_SESSION.headImg}</p></a></p><p><a href="/employee?cmd=input">增加员工</a></p><p><a href="/user?cmd=logout">退出登录</a></p><%--分页跳转的表单--%><form action="/employee" method="post"><table border="1px" cellpadding="0" cellspacing="0"width="800px"><thead><tr><th>序号</th><th>姓名</th><th>工资</th><th>操作</th></tr></thead><tbody><%--动态展示员工列表数据--%><c:forEach items="${pageResult.list}" varStatus="vs" var="employee"><tr class="trClass"><td>${vs.count}</td><td>${employee.name}</td><td>${employee.salary}</td><td><a href="/employee?cmd=input&id=${employee.id}">修改员工信息</a>&nbsp;&nbsp;<%--                    <a href="/employee?cmd=delete&id=${employee.id}">删除员工信息</a>--%><a href="#" onclick="deleteTr(${employee.id})">删除员工信息</a></td></tr></c:forEach></tbody><tfoot><tr align="center"><td colspan="9"><a href="/employee?currentPage=1&pageSize=${pageResult.pageSize}">首页</a>&nbsp;&nbsp;<a href="/employee?currentPage=${pageResult.prevPage}&pageSize=${pageResult.pageSize}">上一页</a>&nbsp;&nbsp;<a href="/employee?currentPage=${pageResult.nextPage}&pageSize=${pageResult.pageSize}">下一页</a>&nbsp;&nbsp;<a href="/employee?currentPage=${pageResult.totalPage}&pageSize=${pageResult.pageSize}">末页</a>&nbsp;&nbsp;当前是第 ${pageResult.currentPage}/${pageResult.totalPage}&nbsp;&nbsp;一共${pageResult.totalCount}条数据&nbsp;&nbsp;跳转到第<input type="text" name="currentPage" value="${pageResult.currentPage}"onchange="changePagesize()" style="width: 50px">&nbsp;&nbsp;每页<select name="pageSize" onchange="changePagesize()"><option value="3" ${pageResult.pageSize==3?'selected':''}>3</option><option value="6" ${pageResult.pageSize==6?'selected':''}>6</option><option value="9" ${pageResult.pageSize==9?'selected':''}>9</option></select>条数据&nbsp;&nbsp;</td></tr></tfoot></table></form>
</center><%--鼠标移动到当前行,实现背景颜色高亮显示--%>
<script>//获取所有的行元素:不包含表头var trs = document.getElementsByClassName("trClass");//遍历行元素集合for(var i=0;i<trs.length;i++){//鼠标移入:当前行高亮,背景变成灰色trs[i].onmouseover=function (){this.style.backgroundColor="gray";}//鼠标移出:恢复原来背景颜色trs[i].onmouseout=function (){this.style.backgroundColor="";}}
</script><%--删除确认表--%>
<script>function deleteTr(id){//确认删除var b= window.confirm("确定要删除选中的员工信息吗?");if(b){//确定删除,执行后台删除操作window.location="/employee?cmd=delete&id="+id;}}
</script><%--分页表单提交函数--%>
<script>function changePagesize(){document.forms[0].submit();}
</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/624529.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决计算机中vcruntime140.dll错误!六种方法教你修复

什么是vcruntime140.dll文件呢&#xff1f;为什么会出现丢失的情况&#xff1f;如何解决这个问题呢&#xff1f;本文将为您详细介绍vcruntime140.dll文件的作用、丢失原因以及6个快速解决方法。 一、vcruntime140.dll是什么文件&#xff1f; vcruntime140.dll是Visual C Redi…

聚合收益协议 InsFi :打开铭文赛道全新叙事的旋转门

​“InsFi 协议构建了一套以铭文资产为基础的聚合收益体系&#xff0c;该体系正在为铭文资产捕获流动性、释放价值提供基础&#xff0c;该生态也正在成为铭文赛道掘金的新热土。” 在 2023 年年初&#xff0c;Ordinals 协议在比特币链上被推出后&#xff0c;为比特币链上带来了…

STC51+TLC2543+ADXL335+proteus

51单片机解析adxl335振动检测蜂鸣器报警课设 通过按键调整振动检测阈值 传感器介绍 TLC2543&#xff1a;12 位精密模数转换器&#xff0c;原理图与引脚功能描述如下所示&#xff1a; 引脚功能1~9、11、12模拟量输入通道10GND电源地13REF-为负基准电压端14REF为正基准电压端…

基于ssm的课程在线教学平台设计与实现论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统Java课程教学信息管理难度大&#xff0c;容错率低&#x…

数据资产入表背后:中国To B数字化驶入“数据时代”

数据资产“入表”&#xff0c;更像是一剂通过颠覆旧的生产关系&#xff0c;从根上医治数字化转型的“良方”。 那么&#xff0c;数据资产到底是什么&#xff1f;以及在愈发被规范的数据市场大背景下&#xff0c;对中国的To B企业和To B服务商而言&#xff0c;正在或者即将发生…

【记忆化搜索】

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【LeetCode】winter vacation training 前言 记忆化搜索是一种优化搜索算法的方法&#xff0c;它可…

基于JavaWeb+BS架构+SpringBoot+Vue基于hive旅游数据的分析与应用系统的设计和实现

基于JavaWebBS架构SpringBootVue基于hive旅游数据的分析与应用系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 1 概 述 5 1.1 研究背景 5 1.2 研究意义 5 1.3 研究内容…

Java实现二维码、条形码生成器

文章目录 前言 在数字化时代&#xff0c;二维码已经成为了信息交流的一种常见方式。它们被广泛用于各种应用&#xff0c;从产品标签到活动传单&#xff0c;以及电子支付。本文将向您展示如何在Spring Boot应用程序中整合ZXing库&#xff0c;以创建和解析QR码。无论您是想为您的…

常用文件文档能做二维码吗?多种文件在线做二维码的方法

二维码是现在工作和生活中随处可见&#xff0c;可以用来展现很多不同的内容。现在很多下发通知的文件、教程或者其他文件内容&#xff0c;也会制作成二维码图片后&#xff0c;让其他人通过扫码来获取文件内容。最简单的制作方法就是通过二维码生成器来制作&#xff0c;支持多种…

【KMP】【二分查找】【C++算法】100207. 找出数组中的美丽下标 II

作者推荐 【矩阵快速幂】封装类及测试用例及样例 本文涉及的基础知识点 二分查找算法合集 LeetCode100207. 找出数组中的美丽下标 II 给你一个下标从 0 开始的字符串 s 、字符串 a 、字符串 b 和一个整数 k 。 如果下标 i 满足以下条件&#xff0c;则认为它是一个 美丽下标…

usb个人总结

一、usb工具分析 1、不同的usb抓包工具抓包分析 2、USB抓包分析方式 外接usb分析仪分析 &#xff08;1&#xff09;力科usb分析仪 &#xff08;2&#xff09;HD-USB12 协议分析仪 &#xff08;3&#xff09;沁恒CH552 usb分析仪&#xff0c;软件工具USB2.0 Monitor (4)等等…

RICHARD MILLE 理查米尔顶级制表技艺典范之作:RM 35-03腕表

瑞士高端制表品牌RICHARD MILLE(理查米尔)在腕表界拥有着卓越的地位,其材质、技术、设计、品质以及服务独树一帜,皆被认为是顶级水平的代表,经典作品数不胜数。而即使在众多经典之作中,RM 35-03 Rafael Nadal 自动上链腕表仍以独特蝶形摆陀和强大性能备受用户推崇,被誉为“RICH…

2024三掌柜赠书活动第三期:Rust系统编程

目录 前言 Rust语言概念 关于《Rust系统编程》 Rust系统编程的核心点 Rust系统编程的关键技术和工具 编辑推荐 内容简介 作者简介 图书目录 书中前言/序言 《Rust系统编程》全书速览 结束语 前言 在技术圈&#xff0c;最近的编程语言新秀当属Rust莫属&#xff0c;R…

2024 解决matplotlib中文字体问题

第一种代码&#xff08;失败代码&#xff09; import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.font_manager import FontPropertiesfont_path /Users/huangbaixi/Desktop/SimHei.ttfdef plot_demo():#print(mpl.get_cachedir())# 绘制折线图font…

操作系统导论-课后作业-ch5

关于man的使用 man 系统参考手册 man n name 在系统手册第n章查看name1. 代码&#xff1a; #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h>int main() {int x 100;int rc fork();if (rc -1) {fprintf…

16位单片机单片机S1C17153

16位单片机单片机 .16KB ROM / 2KB内存 * S1C17653对于程序开发很有用。 .产生具有内置振荡器的操作时钟。 - OSC3B振荡器电路&#xff1a;2MHz/1MHz/500kHz&#xff08;类型&#xff09;内部振荡器电路 -OSC1无振荡器电路&#xff1a;32.768 kHz&#xff08;类型&#xf…

SSL证书与HTTPS的关系

SSL证书是一种数字证书&#xff0c;由权威的证书颁发机构颁发。它包含了一个公钥和有关证书所有者的一些信息&#xff0c;如名称、组织、邮箱等。SSL证书的主要作用是实现数据加密和身份验证&#xff0c;确保数据在传输过程中的安全性和完整性。 HTTPS是一种基于HTTP协议的安全…

༺༽༾ཊ—游戏-01_2D-开发—ཏ༿༼༻

首先利用安装好的Unity Hub创建一个unity 2D&#xff08;URP渲染管线&#xff09;项目 选择个人喜欢的操作格局&#xff08;这里采用2 by 3&#xff09; 在Project项目管理中将双栏改为单栏模式&#xff08;个人喜好&#xff09; 找到首选项&#xff08;Preferences&#xff09…

Django教程第4章 | Web开发实战-三种验证码实现

系列&#xff1a;Django学习教程 验证码的存在是为了防止系统被暴力破解攻击&#xff0c;几乎每个系统都有验证码。下面将介绍三种生成验证码方式。 您可以根据你自己的需要进行学习。 手动生成验证码 安装绘图依赖&#xff0c;利用的是画图模块 PIL 以及随机模块 random 在后…