首页 > 编程语言 >Java实现后端分页

Java实现后端分页

时间:2024-03-20 17:14:25浏览次数:22  
标签:Java 分页 实现 id limit test 查询 page

  分页操作在开发中可以说是最基本的操作,特别是在做各种后台管理系统的时候,不可能一次性查询一千条、一万条数据。

这时候就需要进行分页操作。那么在Java后端当中是如何实现分页的呢?下面就来聊一聊Java后端分页。

Java分页原理

  首先说说分页的原理。有几个名词需要解释一下,数据总数,每页显示的记录数,当前页,总页数。

.1.假设某张表中总条数: total

.2.每页显示记录数:pageSize

.3.当前页:pageNum

.4.总页数:pages

第一步:页面当中需要传入两个数据,每页显示的记录数和当前页;

第二步:查询某张表的总数赋值给total;

第三步:计算总页数 总页数 = Math.ceil(总条数 * 1.0 / 每页显示记录数);

第四步:封装结果返回数据。

说明:总条数 * 1.0表示把一个整数转换为double类型的数据进行计算,否则两个整数相除,计算结果就是一个整数会舍弃掉小数部分。

Math.ceil()表示向上取整。举例每页显示6条数据,如果总共有8条数据,应该显示为2页,而不是1页。

示例一:如果每页显示5条,总数据分别为15,16,19该显示为多少条数据。

Math.ceil(15 * 0.1 / 5) 为3,Math.ceil(16 * 0.1 / 5) 为4,Math.ceil(19 * 0.1 / 5) 为4。符合要求,重点需要理解当最后一页的数据不满一页时,也需要单独显示为一页。

Mysql分页原理

Mysql中分页需要使用一个关键字limit,语法如下

Select * from 表 limit offset,size;

后面跟一个参数或者是两个参数。只跟一个参数表示从第一条记录开始,取size条记录。

如果跟两个参数,第一个参数offset表示偏移量,第二个参数size表示获取的记录数。

下面来做一个简单的测试,建表语句如下,

DROP TABLE IF EXISTS page_test;

CREATE TABLE `page_test` (

 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',

 `name` varchar(16) DEFAULT NULL COMMENT '名称',

 `age` int(11) DEFAULT '0' COMMENT '年龄',

 PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='分页测试表';

测试数据如下,

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('1', '测试名称1', '1');

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('2', '测试名称2', '2');

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('3', '测试名称3', '3');

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('4', '测试名称4', '4');

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('5', '测试名称5', '5');

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('6', '测试名称6', '6');

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('7', '测试名称7', '7');

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('8', '测试名称8', '8');

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('9', '测试名称9', '9');

INSERT INTO `manage`.`page_test` (`id`, `name`, `age`) VALUES ('10', '测试名称10', '10');

下面进行查询测试:

SELECT * FROM page_test order by id asc limit 0,3;

 

SELECT * FROM page_test order by id asc limit 3;

 

上面两个查询语句结果一致。

SELECT * FROM page_test order by id asc limit 1, 3;

 

SELECT * FROM page_test order by id asc limit 3,3;

SELECT * FROM page_test order by id asc limit 6,3;

 

从查询的结果中可以看出,如果每页显示3条数据,limit 0,3表示查询第一页;limit 3,3表示查询第二页;limit 6, 3表示查询第3页。

因此可以推导出一个公式:查询起始位置 = (当前页 - 1) * 每页显示记录数。然后每次分页查询时,动态传入limit后面的两个参数即可。

 

Java代码实现示例

@Getter
@Setter
@NoArgsConstructor
public class PageReSult<T> {

   // 数据总数
   private Integer total;

   // 当前页码
   private Integer pageNum;

   // 每页显示记录数
   private Integer pageSize;

   // 总页数
   private Integer pages;

   // 列表数据
   private List<T> data;
}

说明: Set/get/构造函数使用的是Lombok实现。

 

分页思路如下

.a.获取页面中传递的参数;

.b.查询总条数;

.c.计算mysql中的起始查询位置,查询当前页的数据;

.d.获取当前页的数据;

.e.封装查询结果;

.f.返回数据;

 

具体示例代码如下

@WebServlet("/pageTest")

public class PageTestApi extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 获取分页参数

        String pageNumStr = req.getParameter("pageNum");

        String pageSizeStr = req.getParameter("pageSize");

        // 将分页参数转换为整数

        Integer pageNum = Integer.parseInt(pageNumStr);

        Integer pageSize = Integer.parseInt(pageSizeStr);

        System.out.println("pageNum--->" + pageNum + ";pageSize=" + pageSize);

        // 查询总条数

        String countSql = " SELECT count(*) total FROM page_test ";

        PreparedStatement stmt = null;

        Integer total = 0;

        PageReSult pageReSult = new PageReSult();

        // 使用工具类获取数据库连接

        try (Connection conn = JDBCUtils.getConnection();){

            // 获取数据库操作对象 prepareStatement 可以预编译sql防止sql注入

            stmt = conn.prepareStatement(countSql);

            // 执行查询

            ResultSet rs = stmt.executeQuery();

            // 获取查询结果

            if(rs.next()){

                total = rs.getInt("total");

            }

            System.out.println("total--->" + total);

 

            // 计算 mysql 中 limit 查询的起始位置

            int start = (pageNum - 1) * pageSize;

// 查询分页数据,最好按照某个字段进行排序,否则查询结果可能会不准确

            String selectSql = " SELECT * FROM page_test order by id asc limit ?,?";

            stmt = conn.prepareStatement(selectSql);

            stmt.setObject(1, start);

            stmt.setObject(2, pageSize);

 

            rs = stmt.executeQuery();

            List<EntityTest> data = new ArrayList<>();

            // 获取查询结果集

            while (rs.next()){

                EntityTest entityTest = new EntityTest();

                entityTest.setId(rs.getLong("id"));

                entityTest.setName(rs.getString("name"));

                entityTest.setAge(rs.getInt("age"));

                data.add(entityTest);

            }

 

            // 计算总页数

            Integer pages = (int)Math.ceil(total * 1.0 / pageSize);

            // 封装查询结果

            pageReSult.setTotal(total);

            pageReSult.setPages(pages);

            pageReSult.setPageNum(pageNum);

            pageReSult.setData(data);

            pageReSult.setPageNum(pageNum);

        } catch (SQLException e) {

            throw new RuntimeException("分页查询错误!");

        }

        // 使用工具类返回查询结果

        CommonResult.success(resp, pageReSult);

    }

}

 

每页查询3条数据,测试结果如下:

第一页数据,重点看id为1,2,3.

 

第二页数据,id为4,5,6

 

 

如果每页查询5条数据,查询第二页结果也正确。到此Java后端分页查询功能全部实现。有其他建议的小伙伴,欢迎留言讨论。

标签:Java,分页,实现,id,limit,test,查询,page
From: https://www.cnblogs.com/yilangcode/p/18085642

相关文章

  • Java CC链全分析
    CC链全称CommonsCollections(Java常用的一个库)梦的开始CC1环境部署JDK版本:jdk8u65Maven依赖:<dependencies><!--https://mvnrepository.com/artifact/junit/junit--><dependency><groupId>junit</groupId><......
  • Locust如何实现参数化?
    一、背景我们在测试或者注册的时候,想要的得到不同的结果,这时我们就要用的参数化,比如csv实现数据驱动,等等,那么在locust中我们如何实现参数化呢?案例:模拟三个用户注册账户,要求注册的账户不重复,使用参数化二、实现逻辑这里我们可以用读取本地csv的方式读取数据,并返回一个列表......
  • 操作系统综合题之“采用记录型信号量机制实现上述两个进程的同步算法(代码补充)”
    1.问题:设有无穷多个整数缓冲区(即为无界缓冲池),A进程从输入设备逐个地读入整数并写入缓冲区,B进程则逐个地从缓冲区取出整数进行打印。其中存放整数的变量为item,缓冲区名为buffer,读取过程使用函数getAItem(int*item)来完成,而打印整数使用函数printAItem(intitem)来完成。请用记录......
  • Java学习笔记——第二十一天
    网络编程概述网络编程是可以让设备中的程序与网络上其他设备中的程序实现数据交互的编程技术(实现网络通信的)。Java提供了哪些网络编程的包java.net.*包下提供了网络编程的解决方案。基本的通信架构基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Brow......
  • 操作系统综合题之“采用记录型信号量机制实现爸爸与妈妈进程的同步(爸妈擀饼问题)”
    1.问题:爸爸擀面,妈妈烙饼,面板上只能容纳两张擀好的饼,只有当面板上有空闲空间时,爸爸才能把擀好的饼放在面板上。只有当面板上有时,妈妈才能从面板上取饼。试采用记录型信号量机制实现爸爸与妈妈进程的同步答:设置两个信号量资源:varempty,full:semaphore初始两个资源信号量:empty.......
  • JavaScript 系列教程 II JavaScript 基础知识
    ......
  • 【Java】11k star,一个强大的 Java 版爬虫框架,几行代码即可实现一个爬虫
    From: https://mp.weixin.qq.com/s/rQf4bmHlSucAUlQy7jPNiQwebmagic是一个无须配置、便于二次开发的爬虫框架,它提供简单灵活的API,只需少量代码即可实现一个爬虫。本项目在GitHub上有11.1KStar,非常热门,让不熟悉爬虫的小白也可以玩转爬虫。“申明:此教程仅供爬虫学习交流使用......
  • JavaScript 模块化
    JavaScript模块化JavaScript的历史问题背景JavaScript在一开始诞生的时候只是用来网页脚本的开发,其实没有模块化和命名空间的概念。JS的模块化需求日益增长。幼年期:无模块化模块化思维的萌芽。需要在页面中加载不同的js:动画库,表单库,格式化工具多种js文件被......
  • javascript:void(0);用法及常见问题解析
    javascript:void(0);是一个常见的JavaScript代码片段,通常用于在HTML中作为超链接的href属性值或者事件处理函数的返回值。下面是关于它的用法和常见问题的解析:用法:作为超链接的href属性值:<ahref="javascript:void(0);">点击这里</a>这样做的作用是让点击链......
  • Java调用python服务接口https遇到证书问题的具体解决
    是这样的,大概前一段时间做过一个业务,一直没有记录下来就是我们的算法部,封装好了一系列的算法,然后是python写的。而我们需要用Java去调用他们的方法。如何处理这个问题呢就是我在python里面写了一个rest-api,暴露出几个接口,供Java这边调。但是不知道为什么算法部当时那边弄了个......