SSM虾米音乐项目2--分页查询
1.分页查询的底层逻辑
- 首先根据用户输入的流派,进行模糊查询
- 根据查询的数据进行分页
- 需要前端用户提供pageNo(当前页数)和pageSize(每页的数据量)
- 并且要从后端计算count(总数据量)和totalPage(总页数),以及startNum(每页开始的记录)
- 从而将对应的页面数据展示给用户
2.分页查询的实现
分页查询所需要的所有属性
1.pageNo 当前页码 要查看的页码 前端用户决定
2.pageSize 当前每页的展示数量 前端用户决定或者后台设定好
3.startNum 开始行号 (pageNo-1)*pageSize sql语句做分页要查询的条件,通过计算得出
4.totalNum 所有页数 count/pageSize 通过计算得出
5.List 查询出的数据
6.totalCount 所有数据量 count(*) 通过查询数据库得出
分页查询的代码实现
首先创建分页的对象Page 为泛型类,因为每一个部分都需要实现分页,传递给前端,进行解读
page实体类
package com.qcby.utils;import java.util.List;/*** 封装前端需要的承载数据以及分页相关的一个实体* 自定义页的类*/
public class Page<T> {/*** 每页记录数(已知)*/private Integer pageSize = 5;/*** 页码(已知)*/private Integer pageNo = 1;/*** 指定查询条件下的总记录数(已知)*/private Integer totalCount = 0;/*** 指定查询条件下 的总页数*/private Integer totalPage = 1;/*** 使用sql查询的时候的开始行号*/private Integer startNum = 0;/*** 数据结果集*/private List<T> list;public Integer getPageSize() {return pageSize;}public void setPageSize(Integer pageSize) {this.pageSize = pageSize;}public Integer getPageNo() {return pageNo;}public void setPageNo(Integer pageNo) {this.pageNo = pageNo;}public Integer getTotalCount() {return totalCount;}public void setTotalCount(Integer totalCount) {this.totalCount = totalCount;}public Integer getTotalPage() {totalPage = totalCount/pageSize;if(totalCount == 0 || totalCount%pageSize != 0){//如果不能整除的话,需要取整+1totalPage++;}return totalPage;}public void setTotalPage(Integer totalPage) {this.totalPage = totalPage;}public Integer getStartNum() {return (pageNo -1 )*pageSize;}public void setStartNum(Integer startNum) {this.startNum = startNum;}public List<T> getList() {return list;}public void setList(List<T> list) {this.list = list;}
}
需要将page对象传递给前端,实现对应的页面渲染
mtype实体类
package com.qcby.model;import java.io.Serializable;public class Mtype implements Serializable {private Integer tid;private String tname;private String tdesc;public Mtype() {}public Mtype(Integer tid, String tname, String tdesc) {this.tid = tid;this.tname = tname;this.tdesc = tdesc;}public Integer getTid() {return tid;}public void setTid(Integer tid) {this.tid = tid;}public String getTname() {return tname;}public void setTname(String tname) {this.tname = tname == null ? null : tname.trim();}public String getTdesc() {return tdesc;}public void setTdesc(String tdesc) {this.tdesc = tdesc == null ? null : tdesc.trim();}@Overridepublic String toString() {return "Mtype{" +"tid=" + tid +", tname='" + tname + '\'' +", tdesc='" + tdesc + '\'' +'}';}
}
需要创建mtypeQuery实体类,将前端的页面数据pageNo等的数据,传递给后端进行数据查询,
mtypeQuery实体类
package com.qcby.query;import com.qcby.model.Mtype;/**封装query对象的目的是接受前端的请求参数,在后端处理业务逻辑,*知道用户的分页条件和查询条件* 只作为表现层接收前端参数封装使用*/
public class MtypeQuery extends Mtype{private Integer pageNo;private Integer startNum;private Integer pageSize=5;public Integer getPageSize() {return pageSize;}public void setPageSize(Integer pageSize) {this.pageSize = pageSize;}public Integer getPageNo() {return pageNo;}public void setPageNo(Integer pageNo) {this.pageNo = pageNo;}public Integer getStartNum() {return startNum;}public void setStartNum(Integer startNum) {this.startNum = startNum;}}
为什么mtype实体类当中没有设置有关页面的数据
因为在用page对象对mtype进行封装的时候,页面数据并没有用到前端的数据展示当中,而前端需要向后台服务器传递页面数据,因此需要再创建一个mtypeQuery实体类进行页面数据的封装
表现层
package com.qcby.controller;import com.qcby.model.Mtype;
import com.qcby.utils.Page;
import com.qcby.query.MtypeQuery;
import com.qcby.service.MtypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;/*** 流派业务的表现层* 处理前端页面的请求*/
@Controller
@RequestMapping("/mtype")
public class MtypeController {@Autowiredprivate MtypeService mtypeService;/*** 流派的分页条件查询接口* @param mq* @param model* @return*///展示流派信息@RequestMapping("/list")public String listType(MtypeQuery mq, Model model){if(mq.getPageNo() == null||mq.getPageNo()<=0){mq.setPageNo(1);}Page<Mtype> page = mtypeService.selectObjectByCondition(mq);//把Page对象传递给前端,进行解析呈现数据model.addAttribute("page", page);model.addAttribute("mq",mq);return "mtype";}}
通过model将用户查询到的page传递到前端进行页面渲染
前端用户通过mq将查询条件和分页条件 传递到后端
根据用户的查询条件进行分页的方法selectObjectByCondition需要创建在父接口BaseDao当中,再由浮层的实现类BaseServiceImpl实现,因为所有的类都需要实现该分页操作
BaseDao
package com.qcby.dao;import java.util.List;public interface BaseDao<Q, T> {/*** 保存数据* @param t*/public void insert(T t);/*** 根据主键查询对象* @param id* @return*/public T selectByPrimaryKey(Integer id);/*** 根据主键删除数据* @param id*/public void deleteByPrimaryKey(Integer id);/*** 修改数据* @param*/public void updateByPrimaryKeySelective(T t);/*** 查询所有的记录* @return*/public List<T> selectObjectAll();/*** 根据查询条件来查询数据* @param q* @return*/public List<T> selectObjectByCondition(Q q);/*** 根据查询条件来查询符合条件的记录数* @param q* @return*/public Integer selectObjectByConditionCount(Q q);
}
BaseService
package com.qcby.service;import com.qcby.utils.Page;import java.util.List;public interface BaseService<Q, T> {/*** 保存数据* @param t*/public void insert(T t);/*** 根据主键查询对象* @param id* @return*/public T selectByPrimaryKey(Integer id);/*** 根据主键删除数据* @param id*/public void deleteByPrimaryKey(Integer id);/*** 修改数据* @param*/public void updateByPrimaryKeySelective(T t);/*** 查询所有的记录* @return*/public List<T> selectObjectAll();/*** 分页查询* @param q* @return*/public Page<T> selectObjectByCondition(Q q);
}
BaseServiceImpl实现方法 分页的主要逻辑实现
package com.qcby.service.impl;import com.qcby.dao.BaseDao;
import com.qcby.utils.Page;
import com.qcby.service.BaseService;import java.lang.reflect.Method;
import java.util.List;public class BaseServiceImpl<Q,T> implements BaseService<Q,T> {/*** 可以支持两次注入,但是不好* 选择java基础的权限修饰符,以及set方法注入的形式改成一次注入*/protected BaseDao<Q, T> baseDao;@Overridepublic void insert(T t) {baseDao.insert(t);}@Overridepublic T selectByPrimaryKey(Integer id) {return baseDao.selectByPrimaryKey(id);}@Overridepublic void deleteByPrimaryKey(Integer id) {baseDao.deleteByPrimaryKey(id);}@Overridepublic void updateByPrimaryKeySelective(T t) {baseDao.updateByPrimaryKeySelective(t);}@Overridepublic List<T> selectObjectAll() {return baseDao.selectObjectAll();}//想办法给要返回的page对象所有属性赋值的过程@Overridepublic Page<T> selectObjectByCondition(Q q) {//获得查询对象的类对象//反射Class<? extends Object> qclass = q.getClass();Page<T> page = new Page<T>();try {//获得getPageNo对象Method method = qclass.getMethod("getPageNo", null);//反射调用getPageNo方法Integer pageNo = (Integer) method.invoke(q, null);//创建page对象,给返回去的page设置值page.setPageNo(pageNo);//计算开始行号和结束行号Integer startNum = page.getStartNum();System.out.println(startNum);//好的查询对象 的设置开始行号和结束行号的方法Method setStartNumMethod = qclass.getMethod("setStartNum", new Class[]{Integer.class});setStartNumMethod.invoke(q, startNum);} catch (Exception e) {e.printStackTrace();}//查询结果集List<T> list = baseDao.selectObjectByCondition(q);//查询指定查询条件下的总记录数Integer count = baseDao.selectObjectByConditionCount(q);//把总记录数设置给page对象page.setTotalCount(count);page.setList(list);return page;}
}
为什么要通过使用反射
通过反射获取类的类对象,可以知道当前的类到底对应的具体分页对象是谁。根据传递的q,通过反射调用方法拿到具体的每一个对象的getPageNo和getPageSize,设置给要返回到前端的page对象
MtypeMapper
package com.qcby.dao;import com.qcby.model.Mtype;
import com.qcby.query.MtypeQuery;public interface MtypeMapper extends BaseDao<MtypeQuery,Mtype>{}
MtypeService
package com.qcby.service;import com.qcby.model.Mtype;
import com.qcby.query.MtypeQuery;
import com.qcby.query.MtypeQuery;public interface MtypeService extends BaseService<MtypeQuery,Mtype>{}
MtypeServiceImpl
package com.qcby.service.impl;import com.qcby.query.MtypeQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.qcby.dao.MtypeMapper;
import com.qcby.model.Mtype;
import com.qcby.query.MtypeQuery;
import com.qcby.service.MtypeService;
@Service
public class MtypeServiceImpl extends BaseServiceImpl<MtypeQuery,Mtype> implements MtypeService {private MtypeMapper mtypeMapper;@Autowiredpublic void setMtypeMapper(MtypeMapper mtypeMapper) {this.mtypeMapper = mtypeMapper;this.baseDao=mtypeMapper;}}
前端页面

数据展示前端
<div class="body"><table class="table table-striped table-images"style="color: white;font-size: 14px"><thead><tr><th class="hidden-xs-portrait">序号</th><th class="hidden-xs">流派</th><th class="hidden-xs">描述</th><th></th></tr></thead><tbody><c:forEach items="${page.list}" var="mtype" varStatus="status"><tr><td class="hidden-xs-portrait">${mtype.tid}</td><td class="hidden-xs-portrait">${mtype.tname}</td><td class="hidden-xs"> ${mtype.tdesc} </td><td><button class="btn btn-sm btn-primary" type="button" modify tid="${mtype.tid}" > 修改</button><button data-toggle="button" class="btn btn-sm btn-warning" tid="${mtype.tid}"> 删除</button></td></tr></c:forEach></tbody></table><jsp:include page="pagination.jsp"></jsp:include>
</div>
分页部分前端
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@include file="header.jsp"%>
<html>
<head><title>Title</title>
</head>
<body>
<div class="clearfix text-right"><%--隐藏域--%><input type="hidden" id="pageNo" name="pageNo" value="${mq.pageNo}"><input type="hidden" id="totalPage" value="${page.totalPage}"><ul class="pagination no-margin"><li id="prev" class="disabled"><a href="#">Prev</a></li><c:forEach begin="1" end="${page.totalPage}" var="myPageNo"><li <c:if test="${myPageNo == mq.pageNo}">class="active"</c:if>><a pageNoButton href="#">${myPageNo}</a></li></c:forEach><li id="next"><a href="#">Next</a></li></ul>
</div>
</body>
</html>
上一页和下一页的逻辑
var pageNo = $("#pageNo").val();
var totalPage = $("#totalPage").val();pageNo = parseInt(pageNo);
totalPage = parseInt(totalPage);
//如果已经到首页和尾页,并且只有一页
if (pageNo == 1 && pageNo == totalPage) {$("#prev").addClass("disabled");$("#next").addClass("disabled");
}//如果在首页,且不只有一页
if (pageNo == 1 && pageNo < totalPage) {$("#prev").addClass("disabled");$("#next").removeClass("disabled");
}//如果不只有一页,且不在首页和尾页
if (pageNo > 1 && pageNo < totalPage) {$("#prev").removeClass("disabled");$("#next").removeClass("disabled");
}//如果不只有一页,且不在尾页
if (pageNo > 1 && pageNo == totalPage) {$("#prev").removeClass("disabled");$("#next").addClass("disabled");
}$("#prev").click(function () {$("#pageNo").val(--pageNo);$("#txForm").submit();
})$("#next").click(function () {$("#pageNo").val(++pageNo);$("#txForm").submit();
})$("a[pageNoButton]").click(function () {var pageNo = $(this).html();$("#pageNo").val(pageNo);$("#txForm").submit();
})
相关文章:
SSM虾米音乐项目2--分页查询
1.分页查询的底层逻辑 首先根据用户输入的流派,进行模糊查询根据查询的数据进行分页需要前端用户提供pageNo(当前页数)和pageSize(每页的数据量)并且要从后端计算count(总数据量)和totalPage(总页数),以及startNum(每页开始的记录)从而将对应的页面数据…...
nodejs 获取本地局域网 ip 扫描本地端口
因为傻逼老板的垃圾需求,不得不成长 示例代码: 获取本地局域网 ip 地址: 需要注意的是:如果存在虚拟机网络,则返回的是虚拟机网络的 ipv4 地址 import os from os; export const getLocalIp () > {const in…...
区块链签名种类
1. eth_sign 简介:最早实现的签名方法,用于对任意数据进行签名。签名内容:直接对原始消息的哈希值进行签名。特点: 安全性较低,因为签名的消息没有明确的上下文或结构。很容易被滥用,攻击者可以伪造签名内…...
【062B】基于51单片机无线病房呼叫系统(+时间)【Keil程序+报告+原理图】
☆、设计硬件组成:51单片机最小系统NRF24L01无线模块DS1302时钟芯片LCD1602液晶显示按键设置蜂鸣器LED灯。 1、本设计采用STC89C51/52、AT89C51/52、AT89S51/52作为主控芯片,采用LCD1602液晶显示呼叫信息,系统共有两个板子(一个接…...
突破空间限制!从2D到3D:北大等开源Lift3D,助力精准具身智能操作!
文章链接:https://arxiv.org/pdf/2411.18623 项目链接:https://lift3d-web.github.io/ 亮点直击 提出了Lift3D,通过系统地提升隐式和显式的3D机器人表示,提升2D基础模型,构建一个3D操作策略。 对于隐式3D机器人表示&a…...
【pyspark学习从入门到精通24】机器学习库_7
目录 聚类 在出生数据集中寻找簇 主题挖掘 回归 聚类 聚类是机器学习中另一个重要的部分:在现实世界中,我们并不总是有目标特征的奢侈条件,因此我们需要回归到无监督学习的范式,在那里我们尝试在数据中发现模式。 在出生数据…...
Echart折线图属性设置 vue2
Echart折线图 官方配置项手册 Documentation - Apache ECharts 下面代码包含:设置标题、线条样式、图例圆圈的样式、显示名称格式、图片保存、增加Y轴目标值 updateChart(data) {const sortedData data.slice().sort((a, b) > new Date(a.deviceTime) - ne…...
LabVIEW-简单串口助手
LabVIEW-简单串口助手 串口函数VISA配置串口VISA写入函数VISA读取函数VISA资源名称按名称解除捆绑 函数存放位置思维导图主体界面为以下 串口函数 VISA配置串口 VISA写入函数 VISA读取函数 VISA资源名称 按名称解除捆绑 函数存放位置 思维导图 主体界面为以下 从创建好的“枚举…...
Linux下,用ufw实现端口关闭、流量控制(二)
本文是 网安小白的端口关闭实践 的续篇。 海量报文,一手掌握,你值得拥有,让我们开始吧~ ufw 与 iptables的关系 理论介绍: ufw(Uncomplicated Firewall)是一个基于iptables的前端工具…...
C#开发-集合使用和技巧(九)Join的用法
在C#中,IEnumerable 的 Join 方法用于根据键将两个序列中的元素进行关联。Join 方法通常用于执行类似于 SQL 中的内连接操作。以下是 Join 方法的基本用法: 基本语法 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult…...
Dockerfile容器镜像构建技术
文章目录 1、容器回顾1_容器与容器镜像之间的关系2_容器镜像分类3_容器镜像获取的方法 2、其他容器镜像获取方法演示1_在DockerHub直接下载2_把操作系统的文件系统打包为容器镜像3_把正在运行的容器打包为容器镜像 3、Dockerfile介绍4、Dockerfile指令1_FROM2_RUN3_CMD4_EXPOSE…...
Github 2024-12-01 开源项目月报 Top20
根据Github Trendings的统计,本月(2024-12-01统计)共有20个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10TypeScript项目9Go项目2HTML项目1Shell项目1Jupyter Notebook项目1屏幕截图转代码应用 创建周期:114 天开发语言:TypeScript, Py…...
Spring Boot 3项目集成Swagger3教程
Spring Boot 3项目集成Swagger3教程 ?? 前言 欢迎来到我的小天地,这里是我记录技术点滴、分享学习心得的地方。?? ?? 技能清单 编程语言:Java、C、C、Python、Go、前端技术:Jquery、Vue.js、React、uni-app、EchartsUI设计: Element-u…...
NISP信息安全一级考试200道;免费题库;大风车题库
下载链接:大风车题库-文件 大风车题库网站:大风车题库 大风车excel(试题转excel):大风车excel...
Android ConstraintLayout 约束布局的使用手册
目录 前言 一、ConstraintLayout基本介绍 二、ConstraintLayout使用步骤 1、引入库 2、基本使用,实现按钮居中。相对于父布局的约束。 3、A Button 居中展示,B Button展示在A Button正下方(距离A 46dp)。相对于兄弟控件的约束…...
在网安中什么是白帽子
在网络安全领域,白帽子是指那些专门从事网络安全研究,帮助企业或个人发现并修复安全漏洞的专家。以下是对白帽子的详细解释: 一、定义与角色 白帽子是网络安全领域的术语,通常指那些具备专业技能和知识的网络安全专家。他们的工作…...
软件专业科目难度分级 你输在了哪里?
感想: 我把我们现在软件专业学的东西分了个难度级别 级别描述视角服务对象例子0 基本软件的使用用户-Photoshop wps ssms等1 软件的原理开发者用户各种编程语言2软件的原理的原理开发者开发者各种函数的深层定义,数据结构等 0级就是咱们平时用的那些软…...
微信小程序实现图片拖拽调换位置效果 -- 开箱即用
在编写类似发布朋友圈功能的功能时,需要实现图片的拖拽排序,删除图片等功能。 博主的小程序首页也采用了该示例代码,可以在威信中搜索: 我的百宝工具箱 或者复制后面的🔗在手机打开: #小程序://百宝工具箱/…...
关于“浔川AI翻译”使用情况的调研报告
关于“浔川 AI 翻译”使用情况的调研报告 随着全球化进程加速及外语学习需求攀升,AI 翻译工具愈发普及。“浔川 AI 翻译”作为行业产品之一,为了解其市场表现与用户反馈,特开展本次问卷调查,现将关键结果汇报如下。 一、样本概…...
《芯片:科技之核,未来之路》
《芯片:科技之核,未来之路》 一、芯片的定义与重要性二、芯片的应用领域(一)新能源领域(二)信息通讯设备领域(三)4C 产业(四)智能电网领域(五&…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
