JavaWeb之简单分页查询分析及代码

您所在的位置:网站首页 服务端分页 JavaWeb之简单分页查询分析及代码

JavaWeb之简单分页查询分析及代码

2023-03-09 20:09| 来源: 网络整理| 查看: 265

作者的话:

首先祝大家新年快乐,同样希望大家都可以健健康康的度过这次疫情,然后我想解释一下为什么停更长达一两个月,去年总是可能是熬夜生活作息不太规律,总是偏头痛,程度还挺重,已经影响自己的正常工作和学习,后来配合休息和药,才基本恢复了,上个学期末学校的事也是多了一些,很多时间都用在了课业或者看一些技术书上,所以停更了算挺久,非常抱歉,很感谢即使停更,大家也没有离我而去,从今天起,我接着开始更新一些文章,希望我粗浅的技术能给大家一些切实的帮助,非常欢迎大家用公众号后台,微信或者邮件的方式(文末有联系方式)与我交流,再次感谢大家!

往事随风尽飘散,未来美好盼可期

技术涵盖(JavaWeb、HTML、Ajax、JQuery、Bootstrap )

接触这一部分知识的时候,我们经常会做一些小Demo来练手,不可避免的就需要接触到一定量的数据,我们常常需要将数据从数据库中回显到页面中,但是随着数据量的增加,如果不对数据的查询或者显示进行一定的处理,那么会出现各式各样的问题,例如:

客户端:如果数据同时展示在一个页面中,用户体验效果比较差,操作也是极其不方便服务端:一次请求,查询到所有的数据,数据传输量过大或导致超时或者响应速度变慢,对于服务器的负荷过大分页方式前端 JS 分页 - 不推荐

我们可以请求获取到所有数据后,使用 JavaScript 来进行数据分页显示,单纯的在数据的显示这一方面看确实美观了很多,并且这种分页方式要比后端分页简单很多

但是如果存在一定数据量的情况下,这种方式着实有一些尴尬,他并没有解决了我们服务端的任何问题,反而会让用户在等待响应数据耗时过多,体验不佳,不过它仍然是一种分页方式

在这里我们重点讲解后端分页,所以我们简单的演示一下,也把代码贴出来,由于我们 html 中使用的是 BootStrap 前端框架,所以我们借助了 bootstrap-table 这个前端分页插件

前端 JS 分页 演示代码:

![11.1-01-003](G:\公众号\markdown文件\11-分页与条件查询\分页查询\11.1-01-003.png) 用户信息管理系统 用户信息列表 td, th { text-align: center; } $(function () { $("#userInfo_table").bootstrapTable({ url: 'user/userList', toolbar: '#toolbar', method: 'GET', striped: true, //是否显示行间隔色 cache: false, //是否使用缓存 toolbarAlign: "right", //工具栏对齐方式 sidePagination: "client", //分页方式:client客户端分页,server服务端分页 search: true, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端 uniqueId: "id", pageNumber: 1, //初始化加载第一页 pageSize: 10, //每页的记录行数 pageList: [5, 10, 15, 20], //可供选择的每页的行数 pagination: true, // 是否分页 sortable: true, // 是否启用排序 sortOrder: "asc", //排序方式 showColumns: true, //是否显示列选择按钮 showRefresh: true, //是否显示刷新按钮 clickToSelect: true, //是否启用点击选中行 // height: 500, //行高 showToggle: true, //是否显示详细视图和列表视图的切换按钮 cardView: false, //是否显示详细视图 detailView: false, //是否显示父子表 queryParamsType: '',//设置请求参数格式 queryParams: function queryParams(params) { //设自定义查询参数 /*请求远程数据时,可以通过修改queryParams来发送其他参数。 如果queryParamsType = 'limit',params对象包含:limit,offset,search,sort,order。 否则,它包含:pageSize,pageNumber,searchText,sortName,sortOrder。 返回false停止请求。 默认:function(params) { return params }*/ return params; }, columns: [{ title: "全选", field: "select", checkbox: true, width: 20, //宽度 align: "center", //水平 valign: "middle" //垂直 }, { field: 'uid', title: '编号' }, { field: 'username', title: '用户名' }, { field: 'nickname', title: '昵称' }, { field: 'email', title: '邮箱' }, { field: 'telephone', title: '电话' }, { field: 'gender', title: '性别' }, { field: 'birthday', title: '生日' },{ field: 'id', title: '操作', // width: 120, align: 'center', valign: 'middle', formatter: actionFormatter }] }) }) //操作栏的格式化 function actionFormatter(value, row, index) { var id = row.id; var result = ""; result += "修改"; result += "删除"; return result; } (二) 后端分页 - 推荐

后端分页与前端分页的最大不同就是,它不需要一次性向后端请求大量的数据,而是根据用户的设定,一次请求一定量的数据,然后将这些数据回显到页面上,后端分页也才是分页的正确打开方式,其避免了一次性从数据库获取很多数据,也可以美化前端展示效果,优化用户体验

后端分页的实现方式(一) 整体分析

根据我们上面所讲的,我们需要的就是前端向后端提交请求,后端响应前端需要的数据,并且展示在前端页面中

前端页面中,我们自然需要一个分页条

我们根据需要大致改造一下,增加一个首页和末页,同时增加一个页数以及数据记录统计文字

我们数据涉及到的问题基本就是上图以及响应数据在表格中的回显

① 响应的数据,自然我们需要 将后端所传来包含 用户信息的 list 集合进行遍历回显

即 需要接收并处理一个 List集合

② 总记录数,经后台在数据库查询后给出值

即 需要一个int totalCount 变量 (变量名自行决定)

③ 总页码,可以根据总记录数以及每页展示的条数计算出(后面具体讲)

即 需要一个 int totalPage 变量

④ 当前页码,根据当前页码可以让后台知道你需要的数据是哪些

即 需要一个 int currentPage 变量

⑤ 每页展示的条数,这个值可以暂时写为固定的,改进时,可以交给客户端选择,并且提供给后端

即 需要一个 int pageSize 变量

⑥ 每次查询的起始位置,每次查询时通过 LIMIT 语句进行限制,可以结合每页显示的条数得出

即 需要一个 int start 变量(二) 后端实现 (1) 分页对象

由于前端需要接收到后台传来的需要数据信息,我们可以为上面我们简单分析出所需要的东西,集合成一个分页对象,方便我们的数据传递

//为方便后期调用,加上泛型 public class PageBean { private int totalCount;//总记录数 private int totalPage;//总页数 private int currentPage;//当前页码 private int pageSize;//每页显示的条数 private List list;//每页显示的数据集合 //省略对应构造,get set方法 } (2) Servlet 代码首先需要获取到前端传来的:currentPage、pageSize 两个 String 类型的值如果前端不传递,默认设置 这两个变量的值,若传递值合理,则将其类型转为 int 型(前期可以先忽略这个,或者在前端设置校验)调用 service 查询 PageBean 分页对象,并接收其返回值将PageBean对象序列化为 json 格式,返回@WebServlet("/route/*") public class RouteServlet extends BaseServlet { /** * 分页查询方法 * * @param request * @param response * @throws ServletException * @throws IOException */ public void routeQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String currentPageStr = request.getParameter("currentPage"); //当前页码 String pageSizeStr = request.getParameter("pageSize"); // 每页显示的条数 //当前页码,如果不传递,默认为第1页 int currentPage = 0; if (currentPageStr != null && currentPageStr.length() > 0) { currentPage = Integer.parseInt(currentPageStr); } else { currentPage = 1; } //每页显示条数,如果不传递,默认显示8条记录 int pageSize = 0; if (pageSizeStr != null && pageSizeStr.length() > 0) { pageSize = Integer.parseInt(pageSizeStr); } else { pageSize = 8; } //获取条件查询参数 Map condition = request.getParameterMap(); //调用service查询PageBean对象 RouteService service = new RoutrServiceImpl(); PageBean userPageBean = service.pageQuery(currentPage, pageSize); //将PageBean对象序列化为json,返回 ObjectMapper mapper = new ObjectMapper(); response.setContentType("application/json;"); mapper.writeValue(response.getOutputStream(), userPageBean); } }

说明:以上代码我抽取了Servlet,方便日后扩展方法,刚接触的朋友 直接创建一个 普通的 Servlet 直接在其中编写也是一样可以的,熟悉的朋友,请忽略我这句话

我们需要导入 jackson spring mysql druid 的相关jar包

(3) Service 代码

currentPage 和 pageSize 这两个值已经确定了,我们还需要确定的有:

总记录数 totalCount 和 总页码数 totalPage 以及需要回显到前端页面的 List 集合

总记录数我们直接通过dao层查询就可以了总页码数我们可以通过 (总记录数 / 每页显示的条数) 确定,要注意不能整除需要多出一页查询 需要在前端页面展示的数据 list 我们需要在SQL查询中 使用 LIMIT进行限制,所以我们需要提供查询 的开始点 以及每次 查多少条,这样才能准确的找到这一页 应该是哪些数据被回显到页面中,简单的举举例就能得每一页应该从哪里开始查 即:int start = (currentPage - 1) * pageSizepublic class RouteServiceImpl implements RouteService { private RouteDao routeDao = new RouteDaoImpl(); /** * 分页查询 * * @param currentPage * @param pageSize * @param condition * @return */ @Override public PageBean pageQuery(int currentPage, int pageSize, Map condition) { //创建pageBean对象 PageBean pageBean = new PageBean(); //设置参数 pageBean.setCurrentPage(currentPage); pageBean.setPageSize(pageSize); //调用dao查询总记录数 int totalCount = routeDao.findTotalCount(condition); pageBean.setTotalCount(totalCount); //调用dao查询List集合 int start = (currentPage - 1) * pageSize; List list = routeDao.findByPage(start, pageSize, condition); pageBean.setList(list); //计算总页码 int totalPage = (totalCount % pageSize) == 0 ? totalCount / pageSize : (totalCount / pageSize + 1); pageBean.setTotalPage(totalPage); return pageBean; } } (4) Dao 代码/** * 根据 start pageSize 查询当前页的数据集合 * * @param start * @param pageSize * @return */ @Override public List findByPage(int start, int pageSize) { String sql = "SELECT * FROM user_info LIMIT ? , ?"; return template.query(sql, new BeanPropertyRowMapper(User.class), start, pageSize); } (三) 前端实现

文档载入完毕

$(function () { //暂时的传递两个固定值 var currentPage = 1; var pageSize = 8; //在这里调用具体的功能方法 load(currentPage,pageSize); }); function load(currentPage, pageSize){ //具体的回显代码,下面详细解释这里些什么 }

注意:以下代码均写在 load方法中

(1) ajax 异步提交$.get("route/routeQuery", {currentPage:currentPage,pageSize:pageSize}, function (data){ //传递currentPage、pageSize到后端,同时回调函数返回一个data //下面是具体代码 })

我们下面按照这个流程顺序来进行说明

(2) 数据记录数以及总页码数统计

这一步,只要后台的代码写好了,基本不会出现太大的问题的

$("#pageCount").html("共" + data.totalCount + "条记录,共" + data.totalPage + "页"); (3) 用户信息回显

在HTML 中我们使用了 代码拼接的方式实现了这种需求,这个时候返回的 list集合中的一个User的数据被遍历显示到我们的表格中

('#userInfo_table tr:gt(0)').remove(); var s = ''; for (var i = 0; i < data.list.length; i++) { s += '' + '' + '' + data.list[i].uid + '' + data.list[i].username + '' + data.list[i].nickname + '' + data.list[i].email + '' + data.list[i].telephone + ''+ data.list[i].gender + '' + data.list[i].birthday + ''+ ' 修改' + '' + '


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3