分頁查詢與顯示


分頁查詢與展示

在web項目中經常會有需要展示某個表中所有數據的需求,例如下面的場景:

image-20191219093548936

這個功能實現很簡單,在MVC+DAO的結構下,為DAO增加一個查詢所有的方法,執行select *from xxx就可以獲取所有數據

問題

當表中數據很多時(成千上萬),會不會有問題?

這個問題可以分階段來思考:

  1. DAO層是否能夠一次性從數據庫查詢出所有數據?

  2. 從數據庫返回后,JVM內存是否能夠保存這么多?

  3. View層是否能一次性顯示全部?

  • 第一個問題,由於數據庫底層存儲的是一堆字符串,所以單條數據通常不會占用太多空間,但是一旦數據量超過十萬級,數據大小也會在100MB左右,數據庫底層走的是TCP鏈接,傳輸100MB左右的數據需要一些時間,但是也不會太久,問題不大,除非數據量達到百萬千萬,我們且假設數據沒有這么多

    image-20191219102859676

  • 第二個問題,寫個程序創建10w個對象看看行不行,速度很快,看起來問題不大
    image-20191219102026058

  • 第三個問題,在頁面上顯示10w個圖片試試

image-20191219102405005

打開頁面直接卡死了..

好吧,傻不拉幾的測試過程結束了

最后的結論是客戶端無法一次性展示過多數據,

另外即使一次性真的可以顯示這么多,用戶的使用體驗其實也是很差的,眼花繚亂...

分頁查詢與展示

分頁查詢與展示就是用來解決上述問題

問題的根本原因就在於一次性展示的數據太多,那么解決方案也就是一次性顯示一部分數據,這也是分頁展示的本質

實現分頁:

在MySQL中可以通過limit來對查詢結果進行分段

SQL語法:

select *from tableName limit st,n;

參數解析:

st表示查詢的起始位置,注意從0開始

n表示需要查詢的記錄條數

案例:

每頁顯示3條數據

image-20191219110223936

#如上述顯示第一頁的第1-3條數據,sql語句為:
select *from food limit 0,3;

#第二頁第4-6條數據,sql語句為
select *from food limit 3,3;

#第三頁第4-6條數據,sql語句為
select *from food limit 6,3;

計算起始位置:

可以發現n的值是固定的不會變,但是st的值一直變

開發中不可能在sql中把st的值寫死,需要根據當前的頁碼(第幾頁)來進行計算,

公式:

#設當前頁碼為 p  每頁條數為 n

st = (p-1) * n
#即當前頁碼減去1 乘以每頁條數

計算總頁數:

通常還需要顯示頁碼進度當前頁碼/總頁數

在計算總頁數時必須先獲取數據的總條數,借助聚合函數count來實現

sql語法:

select count(*) from tableName;

有了總條數后,就可以除以每頁條數來得到總頁數

公式:

#設總條數為 c 每頁條數為 n 從頁數為tp
tp = c / n

需要注意的是如果有小數,那么需要向上取整,例如總條數10 每頁3條,10/3 = 3.3,意味着需要4頁才能全部顯示

ok到這里頁面上所有需要的數據都准備好了

總結一下:

  • 要實現分頁的關鍵,在於使用limit關鍵字

  • 頁面需提供兩個參數,當前頁碼, 每頁條數

  • DAO層需要提供兩個方法,獲取某頁的數據,獲取總頁數

請求交互流程

不分離:
image-20191219144144600

需要注意的是由於請求對象是瞬時的,請求完成立即銷毀,所以JSP中的所有參數也就沒有了,我們必須維護當前的頁碼,在JSP和Servlet之間傳遞,這個問題在前后端分離時不存在,前端可以自己維護頁碼

分離:

image-20191219144144600

SQL腳本:

#庫
create database db1 charset utf8;
#表
 CREATE TABLE `food` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(20) DEFAULT NULL,
  `price` float DEFAULT NULL,
  `unit` char(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
);
INSERT INTO `food` VALUES (1,'蘋果',5.8,'500g'),(2,'香蕉',3,'1kg'),(3,'橘子',4,'1kg'),(4,'橙子',6,'500g'),(5,'哈密瓜',8.5,'500g'),(6,'榴蓮',20,'500g'),(7,'雪蓮',4.5,'500g'),(8,'黃瓜',3,'500g'),(9,'辣椒',5.5,'500g'),(10,'葡萄',7,'500g');

源碼:

https://github.com/yangyuanhu/PagingShow.git


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM