java每日精進 5.20【MyBatis 聯表分頁查詢】

1. MyBatis XML 實現分頁查詢

1.1 實現方式

MyBatis XML 是一種傳統的 MyBatis 使用方式,通過在 XML 文件中編寫 SQL 語句,并結合 Mapper 接口和 Service 層實現分頁查詢。分頁需要手動編寫兩條 SQL 語句:一條查詢分頁數據列表,另一條查詢總記錄數。分頁參數(如頁碼和每頁大小)通過 LIMIT 語句手動實現。

1.2 代碼解析

以下是文檔中提供的 MyBatis XML 分頁查詢代碼的解析:

1.2.1 xml代碼

// 獲取所有用戶(分頁,支持用戶名模糊查詢)@GetMapping("/xmluserpage")public IPage<User> getUsersByPage(@RequestParam(defaultValue = "1") int page,@RequestParam(defaultValue = "10") int size,@RequestParam(required = false) String username) {return userService.getUserPage(page, size, username);}
@Overridepublic IPage<User> getUserPage(int page, int size, String username) {Page<User> userPage = new Page<>(page, size);return userMapper.selectPageCustom(userPage, username);}
// 自定義分頁查詢(單表)IPage<User> selectPageCustom(Page<User> page, @Param("username") String username);
<?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.home.mapper.UserMapper"><!-- 自定義分頁查詢 --><select id="selectPageCustom" resultType="com.home.pojo.User">SELECT id, username, password, email, create_time, update_timeFROM user<where><if test="username != null and username != ''">AND username LIKE CONCAT('%', #{username}, '%')</if></where></select></mapper>

2. MyBatis XML 聯表查詢

2.1背景代碼

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>CRUDSystem</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging> <!-- 建議改為jar,Spring Boot默認打包為可執行jar --><name>CRUDSystem</name><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><spring-boot.version>2.7.18</spring-boot.version><mybatis-plus.version>3.5.3.1</mybatis-plus.version><mybatis-plus-join.version>1.4.10</mybatis-plus-join.version></properties><dependencies><!-- MyBatis Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!-- MyBatis Plus Join --><dependency><groupId>com.github.yulichang</groupId><artifactId>mybatis-plus-join-boot-starter</artifactId><version>${mybatis-plus-join.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-extension</artifactId><version>${mybatis-plus.version}</version></dependency><!-- MySQL 驅動 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!-- Spring Boot 核心 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>${spring-boot.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>${spring-boot.version}</version></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version></dependency><!-- 測試依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>${spring-boot.version}</version><scope>test</scope></dependency></dependencies><build><finalName>CRUDSystem</finalName><plugins><!-- Spring Boot 打包插件 --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin><!-- 編譯插件 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>17</source><target>17</target><release>17</release></configuration></plugin></plugins></build>
</project>
@Data
@TableName("user")
public class User {@TableId(type = IdType.AUTO)private Long id;private String username;private String password;private String email;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;
}
@Data
@TableName("`order`")
public class Order {@TableId(type = IdType.AUTO)private Long id;private Long userId;private Long productId;private Integer quantity;private BigDecimal totalPrice;private Integer status;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;
}
//字段平鋪
@Data
public class UserOrderDetailDO extends User {private Long orderId;private BigDecimal totalPrice;private Integer orderStatus;
}
//字段內嵌
@Data
public class UserOrderDetail2DO extends User {private Order order;
}

2.2字段平鋪

// 字段平鋪:獲取用戶訂單詳情(分頁,訂單狀態和用戶名過濾)@GetMapping("/orders")public IPage<UserOrderDetailDO> getUserOrders(@RequestParam(defaultValue = "1") int page,@RequestParam(defaultValue = "10") int size,@RequestParam Integer status,@RequestParam(required = false) String username) {return userService.getUserOrderPage(page, size, status, username);}@Overridepublic IPage<UserOrderDetailDO> getUserOrderPage(int page, int size, Integer status, String username) {Page<UserOrderDetailDO> userOrderPage = new Page<>(page, size);return userMapper.selectListByStatusAndUsername(userOrderPage, status, username);}
// 字段平鋪:聯表查詢用戶和訂單(狀態為已支付,用戶名模糊匹配)default IPage<UserOrderDetailDO> selectListByStatusAndUsername(Page<UserOrderDetailDO> page,@Param("status") Integer status,@Param("username") String username) {return selectJoinPage(page, UserOrderDetailDO.class, new MPJLambdaWrapper<User>() // 改為 selectJoinPage.selectAll(User.class).selectAs(Order::getId, UserOrderDetailDO::getOrderId).selectAs(Order::getTotalPrice, UserOrderDetailDO::getTotalPrice).selectAs(Order::getStatus, UserOrderDetailDO::getOrderStatus).eq(Order::getStatus, status).leftJoin(Order.class, Order::getUserId, User::getId).like(username != null, User::getUsername, username));}

等價于以下SQL

SELECT?
? ? u.*,
? ? o.id AS orderId,
? ? o.total_price AS totalPrice,
? ? o.status AS orderStatus
FROM?
? ? user u
LEFT JOIN?
? ? `order` o ON u.id = o.user_id ?-- 注意這里應該是 user_id 而不是 o.id
WHERE?
? ? o.status = 1?
? ? AND u.username LIKE '%username%'

查詢結果:

{"records": [{"id": 1,"username": "user1","password": "password123","email": "user1@example.com","createTime": "2025-05-20T10:15:33","updateTime": "2025-05-20T10:15:33","orderId": 1,"totalPrice": 999.99,"orderStatus": 1}],"total": 2,"size": 1,"current": 1,"orders": [],"optimizeCountSql": true,"searchCount": true,"maxLimit": null,"countId": null,"pages": 2
}

2.3字段嵌入

// 字段內嵌:獲取用戶訂單詳情(分頁,訂單狀態和用戶名過濾)@GetMapping("/orders2")public IPage<UserOrderDetail2DO> getUserOrders2(@RequestParam(defaultValue = "1") int page,@RequestParam(defaultValue = "10") int size,@RequestParam Integer status,@RequestParam(required = false) String username) {return userService.getUserOrderPage2(page, size, status, username);}
@Overridepublic IPage<UserOrderDetail2DO> getUserOrderPage2(int page, int size, Integer status, String username) {Page<UserOrderDetail2DO> userOrderPage = new Page<>(page, size);return userMapper.selectList2ByStatusAndUsername(userOrderPage, status, username);}
// 字段內嵌:聯表查詢用戶和訂單(狀態為已支付,用戶名模糊匹配)default IPage<UserOrderDetail2DO> selectList2ByStatusAndUsername(Page<UserOrderDetail2DO> page,@Param("status") Integer status,@Param("username") String username) {return selectJoinPage(page, UserOrderDetail2DO.class, new MPJLambdaWrapper<User>() // 改為 selectJoinPage.selectAll(User.class).selectAssociation(Order.class, UserOrderDetail2DO::getOrder).eq(Order::getStatus, status).leftJoin(Order.class, Order::getUserId, User::getId).like(username != null, User::getUsername, username));}

等價SQL:

SELECT?
? ? u.*,?
? ? o.*
FROM?
? ? t_user u
LEFT JOIN?
? ? t_order o ON o.user_id = u.id
WHERE?
? ? o.status = #{status}
? ? AND (#{username} IS NULL OR u.username LIKE CONCAT('%', #{username}, '%'))
LIMIT #{page.size} OFFSET #{page.offset}

返回值為:

{"records": [{"id": 1,"username": "user1","password": "password123","email": "user1@example.com","createTime": "2025-05-20T10:15:33","updateTime": "2025-05-20T10:15:33","order": {"id": 1,"userId": 1,"productId": 1,"quantity": 1,"totalPrice": 999.99,"status": 1,"createTime": "2025-05-20T10:16:00","updateTime": "2025-05-20T10:16:00"}}],"total": 2,"size": 1,"current": 1,"orders": [],"optimizeCountSql": true,"searchCount": true,"maxLimit": null,"countId": null,"pages": 2
}

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

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

相關文章

linux taskset 查詢或設置進程綁定CPU

1、安裝 taskset larkubuntu&#xff1a;~$ sudo apt-get install util-linux larkubuntu&#xff1a;~$ taskset --help 用法&#xff1a; taskset [選項] [mask | cpu-list] [pid|cmd [args...]] 顯示或更改進程的 CPU 關聯性。 選項&#xff1a; -a&#xff0c; --all-tasks…

Python應用字符串格式化初解

大家好!在 Python 編程中&#xff0c;字符串格式化是一項基礎且實用的技能。它能讓你更靈活地拼接字符串與變量&#xff0c;使輸出信息更符合需求。本文將為和我一樣的初學者詳細介紹 Python 字符串格式化的常用方法。 定義: 字符串格式化就是將變量或數據插入到字符串中的特定…

EasyRTC嵌入式音視頻通信SDK一對一音視頻通信,打造遠程辦公/醫療/教育等場景解決方案

一、方案概述? 數字技術發展促使在線教育、遠程醫療等行業對一對一實時音視頻通信需求激增。傳統方式存在低延遲、高畫質及多場景適配不足等問題&#xff0c;而EasyRTC憑借音視頻處理、高效信令交互與智能網絡適配技術&#xff0c;打造穩定低延遲通信&#xff0c;滿足基礎通信…

SEO長尾詞優化精準布局

內容概要 長尾關鍵詞作為SEO策略的核心要素&#xff0c;其價值在于精準捕捉細分需求與低競爭流量入口。相較于短尾詞的高泛化性&#xff0c;長尾詞通過語義擴展與場景化組合&#xff0c;能夠更高效地匹配用戶搜索意圖&#xff0c;降低優化成本的同時提升轉化潛力。本文將從詞庫…

【MySQL】第7節|Mysql鎖機制與優化實踐以及MVCC底層原理剖析

鎖等待分析 我們通過檢查InnoDB_row_lock相關的狀態變量來分析系統上的行鎖的爭奪情況 示例場景 假設有兩個用戶同時操作賬戶表 accounts&#xff08;主鍵為 id&#xff09;&#xff1a; 1. 用戶A&#xff1a;執行轉賬&#xff0c;鎖定賬戶 id1 并等待3秒&#xff1a; BEG…

基于規則引擎與機器學習的智能Web應用防火墻設計與實現

基于規則引擎與機器學習的智能Web應用防火墻設計與實現 引言&#xff1a;智能防御的必然選擇 在2023年OWASP最新報告中&#xff0c;傳統Web應用防火墻&#xff08;WAF&#xff09;對新型API攻擊的漏報率高達67%&#xff0c;而誤報導致的正常業務攔截損失每年超過2.3億美元。面…

GIM發布新版本了 (附rust CLI制作brew bottle流程)

GIM 發布新版本了&#xff01;現在1.3.0版本可用了 可以通過brew upgrade git-intelligence-message升級。 初次安裝需要先執行 brew tap davelet/gim GIM 是一個根據git倉庫內文件變更自動生成git提交消息的命令行工具&#xff0c;參考前文《GIM: 根據代碼變更自動生成git提交…

PyQt5高效布局指南:QTabWidget與QStackedWidget實戰解析

&#x1f50d; 問題背景 當界面控件過多時&#xff0c;直接平鋪會導致窗口擁擠、用戶體驗下降。PyQt5提供了兩種高效容器控件&#xff1a; QTabWidget&#xff1a;選項卡式布局&#xff0c;支持直接切換不同功能模塊QStackedWidget&#xff1a;堆棧式布局&#xff0c;需配合導…

《2.2.1順序表的定義|精講篇》

上一節學習了線性表的邏輯結構&#xff0c;線性表需要實現哪些基本運算/操作&#xff1f;在本節中&#xff0c;我們將學習順序表的定義、順序表的特性&#xff0c;以及如何用代碼來實現順序表。下個小節我們會介紹基于順序存儲&#xff08;這種存儲結構&#xff09;如何用代碼具…

【 大模型技術驅動智能網聯汽車革命:關鍵技術解析與未來趨勢】

大模型技術驅動智能網聯汽車革命&#xff1a;關鍵技術解析與未來趨勢 關鍵詞總結&#xff1a; 大模型技術&#xff1a;LLM、VLM、MLLM、Transformer架構核心場景&#xff1a;智能駕駛、智能座艙、智能網聯關鍵技術&#xff1a;端到端系統、BEVOCC網絡、多模態融合、強化學習挑…

Rocketmq broker 是主從架構還是集群架構,可以故障自動轉移嗎

RocketMQ Broker的架構與故障轉移機制 RocketMQ的Broker架構同時采用了主從架構和集群架構&#xff0c;并且支持故障自動轉移。下面詳細說明&#xff1a; 一、架構類型 1. 集群架構 RocketMQ天然支持分布式集群部署 一個RocketMQ集群包含多個Broker組(每組有主從) 不同Bro…

從零開始建立個人品牌并驗證定位變現性的方法論——基于開源AI大模型、AI智能名片與S2B2C商城生態的實證研究

摘要&#xff1a;本文提出一種融合開源AI大模型、AI智能名片與S2B2C商城小程序源碼的"最小測試閉環"方法論&#xff0c;通過技術賦能實現個人品牌定位的精準驗證與變現路徑優化。以某美妝領域自由職業者為例&#xff0c;其通過開源AI大模型完成能力圖譜構建與資源匹配…

SQL進階之旅 Day 2:高效的表設計與規范:從基礎到實戰

【SQL進階之旅 Day 2】高效的表設計與規范&#xff1a;從基礎到實戰 開篇 在數據庫開發中&#xff0c;一個良好的表設計不僅能夠提高查詢效率&#xff0c;還能避免冗余數據和一致性問題。本文作為"SQL進階之旅"系列的第2天&#xff0c;將重點介紹高效的表設計與規范…

Java—— IO流的應用

帶權重的點名系統 案例要求 文件中有學生的信息&#xff0c;每個學生的信息獨占一行。包括學生的姓名&#xff0c;性別&#xff0c;權重 要求每次被抽中的學生&#xff0c;再次被抽中的概率在原先的基礎上降低一半。 本題的核心就是帶權重的隨機 分析 權重&#xff0c;權重和…

Docker中部署Alertmanager

在 Docker 中部署 Alertmanager&#xff08;通常與 Prometheus 告警系統配合使用&#xff09;的步驟如下&#xff1a; 一、拉取鏡像prom/alertmanager docker pull prom/alertmanager二、 創建 Alertmanager 配置文件 首先準備Alertmanager的配置文件 alertmanager.yml(如存…

【大模型面試每日一題】Day 27:自注意力機制中Q/K/V矩陣的作用與縮放因子原理

【大模型面試每日一題】Day 27&#xff1a;自注意力機制中Q/K/V矩陣的作用與縮放因子原理 &#x1f4cc; 題目重現 &#x1f31f;&#x1f31f; 面試官&#xff1a;請解釋Transformer自注意力機制中Query、Key、Value矩陣的核心作用&#xff0c;并分析為何在計算注意力分數時…

AI+能碳管理系統:全生命周期碳管理

在"雙碳"目標的時代背景下&#xff0c;AI賦能的能碳管理系統正在重新定義企業碳管理的邊界與深度。這套系統猶如一位不知疲倦的碳管家&#xff0c;從原材料采購到產品報廢&#xff0c;在每一個價值環節編織起精密的碳管理網絡&#xff0c;實現從微觀設備到宏觀戰略的…

k8s1.27版本集群部署minio分布式

需求&#xff1a; 1.創建4個pv&#xff0c;一個pv一個minio-pod。使用sts動態分配pvc(根據存儲類找到pv)。----持久化 2.暴露minio的9001端口。&#xff08;nodeport&#xff09;----管理界面 鏡像&#xff1a;minio/minio:RELEASE.2023-03-20T20-16-18Z--->換國內源 說明…

使用 OpenCV 實現 ArUco 碼識別與坐標軸繪制

&#x1f3af; 使用 OpenCV 實現 ArUco 碼識別與坐標軸繪制&#xff08;含Python源碼&#xff09; Aruco 是一種廣泛用于機器人、增強現實&#xff08;AR&#xff09;和相機標定的方形標記系統。本文將帶你一步一步使用 Python OpenCV 實現圖像中多個 ArUco 碼的檢測與坐標軸…

Qt 控件發展歷程 + 目標(1)

文章目錄 聲明簡述控件的發展歷程學習目標QWidget屬性 簡介&#xff1a;這篇文章只是一個引子&#xff0c;介紹一點與控件相關的但不重要的內容&#xff08;瀏覽瀏覽即可&#xff09;&#xff0c;這一章節最為重要的還是要把之后常用且重要的控件屬性和作用給學透&#xff0c;學…