Java實現後端分頁

一只爱阅读的程序员發表於2024-03-20

  分頁操作在開發中可以說是最基本的操作,特別是在做各種後臺管理系統的時候,不可能一次性查詢一千條、一萬條資料。

這時候就需要進行分頁操作。那麼在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條,總資料分別為1516,19該顯示為多少條資料。

Math.ceil(15 * 0.1 / 5) 3Math.ceil(16 * 0.1 / 5) 4Math.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條資料,測試結果如下:

第一頁資料,重點看id1,2,3.

第二頁資料,id4,5,6

如果每頁查詢5條資料,查詢第二頁結果也正確。到此Java後端分頁查詢功能全部實現。有其他建議的小夥伴,歡迎留言討論。

相關文章