Java实现后端分页

🌌 365提款一直在处理中 ⏳ 2026-01-13 14:44:26 👤 admin 👁️ 9911 💖 136
Java实现后端分页

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

这时候就需要进行分页操作。那么在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@NoArgsConstructorpublic class PageReSult { // 数据总数 private Integer total; // 当前页码 private Integer pageNum; // 每页显示记录数 private Integer pageSize; // 总页数 private Integer pages; // 列表数据 private List 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 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后端分页查询功能全部实现。有其他建议的小伙伴,欢迎留言讨论。

相关文章