MyBatis初級實戰之六:一對多關聯查詢
阿新 • • 發佈:2021-01-22
### 歡迎訪問我的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