1. 程式人生 > >MyBatis初級實戰之六:一對多關聯查詢

MyBatis初級實戰之六:一對多關聯查詢

### 歡迎訪問我的GitHub [https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) 內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等; ### 本篇概覽 - 本文是《MyBatis初級實戰》系列的第六篇,繼續實踐從多表獲取資料; - 回顧上一篇,咱們實戰了多表關聯的一對一關係,如下圖所示,查詢日誌記錄時,把對應的使用者資訊查出: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210122074747422-1942973624.jpg) - 本篇要實踐的是一對多關係:查詢使用者記錄時,把該使用者的所有日誌記錄都查出來,邏輯關係如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210122074747969-942405540.jpg) - 在具體編碼實現一對多查詢時,分別使用聯表和巢狀兩種方式實現,每種方式都按照下圖的步驟執行: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210122074748321-597931846.jpg) ### 原始碼下載 1. 如果您不想編碼,可以在GitHub下載所有原始碼,地址和連結資訊如下表所示(https://github.com/zq2599/blog_demos): | 名稱 | 連結 | 備註| | :-------- | :----| :----| | 專案主頁| https://github.com/zq2599/blog_demos | 該專案在GitHub上的主頁 | | git倉庫地址(https)| https://github.com/zq2599/blog_demos.git | 該專案原始碼的倉庫地址,https協議 | | git倉庫地址(ssh)| [email protected]:zq2599/blog_demos.git | 該專案原始碼的倉庫地址,ssh協議 | 2. 這個git專案中有多個資料夾,本章的應用在mybatis資料夾下,如下圖紅框所示: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210122074748619-1022109746.png) 3. mybatis是個父工程,裡面有數個子工程,本篇的原始碼在relatedoperation子工程中,如下圖紅框所示: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210122074749233-1971121638.jpg) ### 準備資料 1. 本次實戰,在名為mybatis的資料庫中建立兩個表(和前面幾篇文章中的表結構一模一樣):user和log表; 2. user表記錄用戶資訊,非常簡單,只有三個欄位:主鍵、名稱、年齡 3. log表記錄用戶行為,四個欄位:主鍵、使用者id、行為描述、行為時間 4. user和log的關係如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210122074749693-1745658186.jpg) 5. 建表和新增資料的語句如下: ```sql use mybatis; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(32) NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL, `age` int(32) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `log`; CREATE TABLE `log` ( `id` int(32) NOT NULL AUTO_INCREMENT, `user_id` int(32), `action` varchar(255) NOT NULL, `create_time` datetime not null, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; INSERT INTO mybatis.user (id, name, age) VALUES (3, 'tom', 11); INSERT INTO mybatis.log (id, user_id, action, create_time) VALUES (3, 3, 'read book', '2020-08-07 08:18:16'); INSERT INTO mybatis.log (id, user_id, action, create_time) VALUES (4, 3, 'go to the cinema', '2020-09-02 20:00:00'); INSERT INTO mybatis.log (id, user_id, action, create_time) VALUES (5, 3, 'have a meal', '2020-10-05 12:03:36'); INSERT INTO mybatis.log (id, user_id, action, create_time) VALUES (6, 3, 'have a sleep', '2020-10-06 13:00:12'); INSERT INTO mybatis.log (id, user_id, action, create_time) VALUES (7, 3, 'write', '2020-10-08 09:21:11'); ``` ### 關於多表關聯查詢的兩種方式 - 多表關聯查詢的實現有聯表和巢狀查詢兩種,它們的差異在Mybatis中體現在resultMap的定義上: 1. 聯表時,resultMap內使用collection子節點,將聯表查詢的結果對映到關聯物件集合; 2. 巢狀時,resultMap內使用association子節點,association的select屬性觸發一次新的查詢; - 上述兩種方式都能成功得到查詢結果,接下來逐一嘗試; ### 聯表查詢 1. 本篇繼續使用上一篇中建立的子工程relatedoperation; 2. 實體類UserWithLogs.java如下,可見成員變數logs是用來儲存該使用者所有日誌的集合: ```java package com.bolingcavalry.relatedoperation.entity; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; @Data @NoArgsConstructor @ApiModel(description = "使用者實體類(含行為日誌集合)") public class UserWithLogs { @ApiModelProperty(value = "使用者ID") private Integer id; @ApiModelProperty(value = "使用者名稱", required = true) private String name; @ApiModelProperty(value = "使用者地址", required = false) private Integer age; @ApiModelProperty(value = "行為日誌", required = false) priv