Spring Boot項目如何使用MyBatis實現分頁查詢

?寫在前面:大家好!我是晴空?。如果博客中有不足或者的錯誤的地方歡迎在評論區或者私信我指正,感謝大家的不吝賜教。我的唯一博客更新地址是:https://ac-fun.blog.csdn.net/。非常感謝大家的支持。一起加油,沖鴨!
?用知識改變命運,用知識成就未來!加油 (? ??o??)? (? ??o??)?

文章目錄

  • 為什么需要分頁查詢
    • 減少數據庫壓力
    • 減少網絡傳輸數據量
    • 提高系統的穩定性
    • 提升用戶體驗
  • 原始的實現方式
    • 計算偏移量
    • 在Mapper接口中定義查詢方法
    • 編寫SQL語句
    • 開發流程及完整代碼
      • Controller層
      • Service實現類
      • Mapper接口方法
      • xml文件SQL
  • 使用插件實現
    • 引入分頁插件依賴
    • Service實現類
    • xml文件SQL
    • 與原始分頁的不同

為什么需要分頁查詢

?分頁查詢是一種常見的數據庫查詢技術,用于將查詢結果分成多個頁面展示,而不是一次性返回所有數據。使用分頁查詢主要是為了減少數據庫壓力、減少網絡傳輸數據量、提高系統的穩定性、提高客戶體驗

減少數據庫壓力

?一次性查詢全部數據(例如百萬條記錄)會占用大量的資源(CPU、內存、I/O),導致響應變慢甚至系統崩潰。分頁后,每次僅查詢少量數據(如每頁100條),可以顯著降低負載。
查詢執行路徑

減少網絡傳輸數據量

?分頁查詢每次只傳輸當前頁的數據,相比于全表查詢會極大的減少網絡傳輸的數據量,降低網絡帶寬的占用。

提高系統的穩定性

?后端服務處理分頁查詢時,單次處理的數據量可控,避免因一次性加載大數據導致內存耗盡出現 OOM 問題。對于前端也由于無需一次性渲染大量的數據而減少了內存崩潰的風險。

提升用戶體驗

?分頁查詢由于單次查詢的數據量少,后端與前端可以快速的處理相關的數據。用戶無需進行長時間的等待,極大的提高了客戶的體驗。

原始的實現方式

?如果不使用分頁查詢相關的插件需要我們自己計算分頁查詢的偏移量offset,還需要手動查詢結果集以及數據總條數,并且在相關的 Mapper.xml 中定義分頁查詢的 SQL 語句。主要實現步驟如下:

計算偏移量

?手動分頁查詢需要我們通過在 SQL 語句中添加分頁相關的語法來實現,例如在 MySQL 中的語法:

SELECT * FROM users LIMIT #{pageSize} offset #{offset};

其中,#{offset} 表示偏移量,但是前端的分頁查詢請求中一般只有查詢第幾頁 page 和每頁的大小 pageSize。需要我們先計算一下偏移量是多少。

?需要注意前端傳的 page 是從 0 開始的還是從 1 開始的。

  • 0 開始則 offset = page * pageSize
  • 1 開始則 offset = (page - 1) * pageSize

在Mapper接口中定義查詢方法

/*** 分頁查詢結果集* @param page* @param offset* @param name* @param categoryId* @param status* @return*/
List<DishVO> pageQuery(int page, int offset, String name, Integer categoryId, Integer status);/*** 查詢總條數* @return*/
int getTotalSize();

編寫SQL語句

<mapper namespace="com.sky.mapper.DishMapper"><insert id="insert" useGeneratedKeys="true" keyProperty="id">insert into dish (name, category_id, price, image, description, status, create_time, update_time, create_user, update_user)values (#{name}, #{categoryId}, #{price}, #{image}, #{description},#{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})</insert><select id="pageQuery" resultType="com.sky.vo.DishVO">select d.*, c.name as categoryName from dish d left outer join category c on d.category_id = c.id<where><if test="name != null">and d.name like concat('%', #{name}, '%')</if><if test="categoryId != null">and d.category_id = #{categoryId}</if><if test="status != null">and d.status = #{status}</if></where>order by d.create_time desclimit #{page}offset #{offset}</select><select id="getTotalSize" resultType="java.lang.Integer">select count(*) from dish;</select>
</mapper>

開發流程及完整代碼

?在開發過程中 由外而內 進行開發效率會更高一些,我們一般不需要先寫 Mapper.xml 中的 SQL語句,再定義Mapper接口中的方法,然后再通過 Service類 中進行調用。

?一般會從 Service類 開始寫起,然后再通過編輯器的快捷方式幫助我們生成相關的代碼,再一層一層的實現。

Controller層

@GetMapping("/page")
@ApiOperation("菜品分頁查詢")
public Result<PageResult> pageQuery(DishPageQueryDTO dishPageQueryDTO) {log.info("菜品分頁查詢開始[{}]", dishPageQueryDTO);return dishService.pageQuery(dishPageQueryDTO);
}

Service實現類

@Override
public Result<PageResult> pageQuery(DishPageQueryDTO dishPageQueryDTO) {// 計算偏移量int offset = (dishPageQueryDTO.getPage() - 1) * dishPageQueryDTO.getPageSize();// 查詢當前頁的數據List<DishVO> dishVOList = dishMapper.pageQuery(dishPageQueryDTO.getPageSize(), offset, dishPageQueryDTO.getName(),dishPageQueryDTO.getCategoryId(), dishPageQueryDTO.getStatus());// 查詢數據庫中的總條數int total = dishMapper.getTotalSize();PageResult pageResult = new PageResult();pageResult.setTotal(total);pageResult.setRecords(dishVOList);log.info("分頁查詢結果為[{}]", pageResult);return Result.success(pageResult);
}

Mapper接口方法

/*** 分頁查詢結果集* @param page* @param offset* @param name* @param categoryId* @param status* @return*/
List<DishVO> pageQuery(int page, int offset, String name, Integer categoryId, Integer status);/*** 查詢總條數* @return*/
int getTotalSize();

xml文件SQL

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.DishMapper"><insert id="insert" useGeneratedKeys="true" keyProperty="id">insert into dish (name, category_id, price, image, description, status, create_time, update_time, create_user, update_user)values (#{name}, #{categoryId}, #{price}, #{image}, #{description},#{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})</insert><select id="pageQuery" resultType="com.sky.vo.DishVO">select d.*, c.name as categoryName from dish d left outer join category c on d.category_id = c.id<where><if test="name != null">and d.name like concat('%', #{name}, '%')</if><if test="categoryId != null">and d.category_id = #{categoryId}</if><if test="status != null">and d.status = #{status}</if></where>order by d.create_time desclimit #{page}offset #{offset}</select><select id="getTotalSize" resultType="java.lang.Integer">select count(*) from dish;</select>
</mapper>

使用插件實現

?使用分頁插件可以極大的簡化分頁查詢實現。雖然實現的主要原理還是通過原始實現方式中提到的邏輯,但是通過分頁插件我們就可以少寫很多代碼而且一般分頁插件(例如 PageHelper) 會通過動態 SQL 的構建和優化,能夠有效避免傳統分頁方法的性能問題。

?使用插件進行分頁查詢只需要修改一下上述原始實現方式的Service類xml 文件中的 SQL 語句即可。

引入分頁插件依賴

<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>

Service實現類

@Override
public Result<PageResult> pageQuery(DishPageQueryDTO dishPageQueryDTO) {PageHelper.startPage(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());Page<DishVO> page = dishMapper.pageHelperQuery(dishPageQueryDTO);PageResult pageResult = new PageResult();pageResult.setTotal(page.getTotal());pageResult.setRecords(page.getResult());log.info("分頁查詢結果為[{}]", pageResult);return Result.success(pageResult);}

xml文件SQL

<select id="pageHelperQuery" resultType="com.sky.vo.DishVO">select d.*, c.name as categoryName from dish d left outer join category c on d.category_id = c.id<where><if test="name != null">and d.name like concat('%', #{name}, '%')</if><if test="categoryId != null">and d.category_id = #{categoryId}</if><if test="status != null">and d.status = #{status}</if></where>order by d.create_time desc
</select>

與原始分頁的不同

?使用分頁插件進行分頁不需要手動計算分頁查詢的偏移量,在寫SQL語句時也不需要顯式地使用 LIMITOFFSET 來實現分頁。而且分頁插件也會直接將查詢的結果集總條數封裝到 Page對象 中,不需要我們手動的查詢結果集和總條數。


  1. mysql開啟緩存、設置緩存大小、緩存過期機制
  2. PageHelper分頁插件最新源碼解讀及使用
  3. 蒼穹外賣

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67751.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67751.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67751.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【論文筆記】Fast3R:前向并行muti-view重建方法

眾所周知&#xff0c;DUSt3R只適合做稀疏視角重建&#xff0c;與sapnn3r的目的類似&#xff0c;這篇文章以并行的方法&#xff0c;擴展了DUSt3R在多視圖重建中的能力。 abstract 多視角三維重建仍然是計算機視覺領域的核心挑戰&#xff0c;尤其是在需要跨不同視角實現精確且可…

本地部署DeepSeek教程(Mac版本)

第一步、下載 Ollama 官網地址&#xff1a;Ollama 點擊 Download 下載 我這里是 macOS 環境 以 macOS 環境為主 下載完成后是一個壓縮包&#xff0c;雙擊解壓之后移到應用程序&#xff1a; 打開后會提示你到命令行中運行一下命令&#xff0c;附上截圖&#xff1a; 若遇…

deepseek本地部署會遇到哪些坑

在本地部署DeepSeek(或其他類似AI模型)時,可能會遇到以下常見問題及解決方案: 1. 硬件資源不足 問題表現: GPU不兼容(如型號過舊)、顯存不足(OOM錯誤)或CPU模式性能極低。解決方案: 確認GPU支持CUDA,檢查顯存需求(如至少16GB顯存)。使用nvidia-smi監控顯存,通過降…

微機原理與接口技術期末大作業——4位搶答器仿真

在微機原理與接口技術的學習旅程中&#xff0c;期末大作業成為了檢驗知識掌握程度與實踐能力的關鍵環節。本次我選擇設計并仿真一個 4 位搶答器系統&#xff0c;通過這個項目&#xff0c;深入探索 8086CPU 及其接口技術的實際應用。附完整壓縮包下載。 一、系統設計思路 &…

解決國內服務器 npm install 卡住的問題

在使用國內云服務器時&#xff0c;經常會遇到 npm install 命令執行卡住的情況。本文將分享一個典型案例以及常見的解決方案。 問題描述 在執行以下命令時&#xff1a; mkdir test-npm cd test-npm npm init -y npm install lodash --verbose安裝過程會卡在這個狀態&#xf…

【Redis】Redis 經典面試題解析:深入理解 Redis 的核心概念與應用

Redis 是一個高性能的鍵值存儲系統&#xff0c;廣泛應用于緩存、消息隊列、排行榜等場景。在面試中&#xff0c;Redis 是一個高頻話題&#xff0c;尤其是其核心概念、數據結構、持久化機制和高可用性方案。 1. Redis 是什么&#xff1f;它的主要特點是什么&#xff1f; 答案&a…

昆侖萬維Java開發面試題及參考答案

進程和線程的區別是什么? 進程和線程都是操作系統中非常重要的概念,它們在多個方面存在顯著的區別。 從定義上看,進程是操作系統進行資源分配和調度的基本單位。每個進程都有自己獨立的內存空間,包括代碼段、數據段、堆棧段等。例如,當你在電腦上同時打開瀏覽器和音樂播放…

Visual Studio Code應用本地部署的deepseek

1.打開Visual Studio Code&#xff0c;在插件中搜索continue&#xff0c;安裝插件。 2.添加新的大語言模型&#xff0c;我們選擇ollama. 3.直接點connect&#xff0c;會鏈接本地下載好的deepseek模型。 參看上篇文章&#xff1a;deepseek本地部署-CSDN博客 4.輸入需求生成可用…

DeepSeek技術深度解析:從不同技術角度的全面探討

DeepSeek技術深度解析&#xff1a;從不同技術角度的全面探討 引言 DeepSeek是一個集成了多種先進技術的平臺&#xff0c;旨在通過深度學習和其他前沿技術來解決復雜的問題。本文將從算法、架構、數據處理以及應用等不同技術角度對DeepSeek進行詳細分析。 一、算法層面 深度學…

SpringBoot 整合 Mybatis:注解版

第一章&#xff1a;注解版 導入配置&#xff1a; <groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.1</version> </dependency> 步驟&#xff1a; 配置數據源見 Druid…

[Linux]如何將腳本(shell script)轉換到系統管理服務器(systemd service)來運行?

[InfluxDB]Monitor Tem. and Volt of RaspberryPi and Send Message by Line Notify 在Linux中&#xff0c;shell腳本(shell script)常用於運行各種自動化的流程&#xff0c;包含API串接&#xff0c;設置和啟動應用服務等等&#xff0c;腳本語法也相對易學易讀&#xff0c;因此…

2025年最新在線模型轉換工具優化模型ncnn,mnn,tengine,onnx

文章目錄 引言最新網址地點一、模型轉換1. 框架轉換全景圖2. 安全的模型轉換3. 網站全景圖 二、轉換說明三、模型轉換流程圖四、感謝 引言 在yolov5&#xff0c;yolov8&#xff0c;yolov11等等模型轉換的領域中&#xff0c;時間成本常常是開發者頭疼的問題。最近發現一個超棒的…

理解知識蒸餾中的散度損失函數(KLDivergence/kldivloss )-以DeepSeek為例

1. 知識蒸餾簡介 什么是知識蒸餾&#xff1f; 知識蒸餾&#xff08;Knowledge Distillation&#xff09;是一種模型壓縮技術&#xff0c;目標是讓一個較小的模型&#xff08;學生模型&#xff0c;Student Model&#xff09;學習一個較大、性能更優的模型&#xff08;教師模型…

Electron使用WebAassembly實現CRC-8 MAXIM校驗

Electron使用WebAssembly實現CRC-8 MAXIM校驗 將C/C語言代碼&#xff0c;經由WebAssembly編譯為庫函數&#xff0c;可以在JS語言環境進行調用。這里介紹在Electron工具環境使用WebAssembly調用CRC-8 MAXIM格式校驗的方式。 CRC-8 MAXIM校驗函數WebAssebly源文件 C語言實現CR…

Vue3.0實戰:大數據平臺可視化

文章目錄 創建vue3.0項目項目初始化項目分辨率響應式設置項目頂部信息條創建頁面主體創建全局引入echarts和axios后臺接口創建express銷售總量圖實現完整項目下載項目任何問題都可在評論區,或者直接私信即可。 創建vue3.0項目 創建項目: vue create vueecharts選擇第三項:…

vector容器(詳解)

本文最后是模擬實現全部講解&#xff0c;文章穿插有彩色字體&#xff0c;是我總結的技巧和關鍵 1.vector的介紹及使用 1.1 vector的介紹 https://cplusplus.com/reference/vector/vector/&#xff08;vector的介紹&#xff09; 了解 1. vector是表示可變大小數組的序列容器。…

Ubuntu 下 nginx-1.24.0 源碼分析 ngx_debug_init();

目錄 ngx_debug_init() 函數&#xff1a; NGX_LINUX 的定義&#xff1a; ngx_debug_init() 函數&#xff1a; ngx_debug_init() 函數定義在 src\os\unix 目錄下的 ngx_linux_config.h 中 #define ngx_debug_init() 也就是說這個環境下的 main 函數中的 ngx_debug_init() 這…

Airflow:深入理解Apache Airflow Task

Apache Airflow是一個開源工作流管理平臺&#xff0c;支持以編程方式編寫、調度和監控工作流。由于其靈活性、可擴展性和強大的社區支持&#xff0c;它已迅速成為編排復雜數據管道的首選工具。在這篇博文中&#xff0c;我們將深入研究Apache Airflow 中的任務概念&#xff0c;探…

開發環境搭建-4:WSL 配置 docker 運行環境

在 WSL 環境中構建&#xff1a;WSL2 (2.3.26.0) Oracle Linux 8.7 官方鏡像 基本概念說明 容器技術 利用 Linux 系統的 文件系統&#xff08;UnionFS&#xff09;、命名空間&#xff08;namespace&#xff09;、權限管理&#xff08;cgroup&#xff09;&#xff0c;虛擬出一…

JavaScript 基礎 - 7

關于JS函數部分的學習和一個案例的練習 1 函數封裝 抽取相同部分代碼封裝 優點 提高代碼復用性&#xff1a;封裝好的函數可以在多個地方被重復調用&#xff0c;避免了重復編寫相同的代碼。例如&#xff0c;編寫一個計算兩個數之和的函數&#xff0c;在多個不同的計算場景中都…