MyBatis | 映射文件之 ResultMap(二)

在上一篇文章 MyBatis | 映射文件之 ResultMap(一)中霍殴,簡述了如何使用 ResultMap,以及如何使用 ResultMap 進行一對一的關聯查詢刀诬。這一篇我將說明如何使用 ResultMap 進行一對多的關聯查詢

一、說明與準備

為了便于學習,我仍然會貼出表結構和 POJO 的設計章姓,下面是實驗前的環(huán)境搭建

employee 的 dept_id 關聯 department 表的 id 字段,即 id 是 dept_id 的外鍵识埋。這和上一篇的創(chuàng)建是一致的

employee表

department 表

Employee.java

public class Employee {

    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;
    private Department department;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
        ...
}

Department:這里我設置了一個類型為 Employee 的 List 集合凡伊,對應數據庫表中一個部門可以有多個員工

public class Department {

    private Integer id;
    private String departName;
    private List<Employee> employees;
    
    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }
    
    public List<Employee> getEmployees() {
        return employees;
    }
        ...
}


二、使用 ResultMap 進行一對多關聯查詢

需求是窒舟,使用 sql 語句系忙,查詢出每個部門的信息,以及每個部門所關聯的員工信息惠豺。由于一個部門對應多個員工银还,即一對多风宁,這里我們使用 LEFT JOIN 對字段進行連接

1. 使用 collection 進行兩張表的關聯查詢

類似于上一篇中介紹的一對一的關聯查詢,不過上一篇中關聯的是一個對象蛹疯,不這里關聯的是一個集合戒财。至于 collection,我會結合代碼進行講解

①. 首先創(chuàng)建一個集合類
DepartmentMapper.java

public interface DepartmentMapper {
    public Department getDepartmentAndList(Integer id);
}



②. 配置 sql 映射文件
下面是 DepartmentMapper.xml 的配置信息捺弦,sql 語句如下饮寞,當然是使用外鍵關聯

<select id="getDepartmentAndList" resultMap="dept">
    SELECT d.id did, d.depart_name, e.id eid, e.last_name, email, gender 
    FROM department d 
    LEFT JOIN employee e 
    ON d.id = e.dept_id 
    WHERE d.id = #{id}
</select>

接下來寫 resultMap 的配置:外層的 id 和 result 標簽,是配置 Department 類(表)的列吼,collection 標簽里面的 id 和 result 標簽骂际,都是用來配置與 Department 類關聯的 Employee 類(表)的。(PS:由于我在 mybatis.xml 主配置文件中配置了使用別名冈欢,因此類型都是以別名顯示歉铝。否則需要全類名。)

collection 標簽里定義的集合對象凑耻,這里定義的是 Employee 類型的集合
property:指定 Department 對象里面包含的 Employee 集合對象太示,即 List<Employee> employees
ofType:指定集合的類型

<!-- 使用嵌套結果集的方式, 使用 collection 標簽定義關聯的集合類型的封裝規(guī)則 -->
<resultMap type="Department" id="dept">
    <!-- Deparment 類的配置 -->
    <id column="id" property="id"/>
    <result column="depart_name" property="departName"/>
    
    <!-- Employee 類的配置 -->
    <collection property="employees" ofType="Employee">
        <id column="id1" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </collection>
</resultMap>


③. 結果
測試語句我不寫了,我們傳入 Employee 的 id 為 1香浩,直接貼出結果

Department [id=1, departName=開發(fā)部]
[Employee [id=1, lastName=Tom, email=tom@126.com, gender=0], 
Employee [id=2, lastName=Peter, email=peter@qq.com, gender=1], 
Employee [id=7, lastName=ljk, email=lkj@123.com, gender=1], 
Employee [id=15, lastName=lkj, email=lkj@123.com, gender=2]]

同時貼出使用同樣 sql 語句和同樣 id 的數據庫查詢的結果

+-----+-------------+------+-----------+--------------+--------+
| did | depart_name | eid  | last_name | email        | gender |
+-----+-------------+------+-----------+--------------+--------+
|   1 | 開發(fā)部      |    1 | Tom       | tom@126.com  |      0 |
|   1 | 開發(fā)部      |    2 | Peter     | peter@qq.com |      1 |
|   1 | 開發(fā)部      |    7 | ljk       | lkj@123.com  |      1 |
|   1 | 開發(fā)部      |   15 | lkj       | lkj@123.com  |      2 |
+-----+-------------+------+-----------+--------------+--------+

可以看到类缤,使用 resultMap 查詢出來的結果和數據庫查詢的結果一致,而且 Employee 確實是以 List 集合的形式出現的邻吭。

???遇到的坑:
在查詢的過程中餐弱,遇到了一個畢竟大的坑??,當時找了快幾個小時╯︿╰囱晴,這里說明一下膏蚓,防患于未來。畸写。
先斬后奏把驮瞧。column 里面的值一定要與查詢出來的列名相一致, 如果使用列的別名, 則 column 的值就是列的別名

拿上面的 sql 為例,我們看一下使用別名查詢出來的列名

| did | depart_name | eid | last_name | email | gender |

以 id 這個字段為例子枯芬,我們注意一下 resultMap 里面配置的兩個 id 標簽對應的 column 對應的值论笔,可以看到對應的是 sql 語句(SELECT d.id did, e.id eid ... FROM department d...)中設置的別名 dideid

<resultMap type="Department" id="dept">
    <id column="did" property="id"/>
    ...
    <collection property="employees" ofType="Employee">
        <id column="eid" property="id"/>
        ....
    </collection>
</resultMap>

如果你沒有設置別名(SELECT d.id, e.id ... FROM department d...)千所,同時你在兩個 id 標簽的 column 直接填 id狂魔,那么就會出問題。淫痰。血的教訓??

| id | depart_name | id1 | last_name | email | gender |

不用別名查詢出來的表的列名結構是這樣的最楷,如果真要用,可以這樣配置。這樣也是可以查詢出結果的管嬉,不過并不推薦皂林。還是使用別名把!r橇谩础倍!

<resultMap type="Department" id="dept">
    <id column="d1" property="id"/>
    ...
    <collection property="employees" ofType="Employee">
        <id column="id1" property="id"/>
        ....
    </collection>
</resultMap>


2. 使用 collection 進行兩張表的分布查詢

使用 association 進行分布查詢,實則分三步:

  1. 先根據部門 id 查詢出部門所有信息:select * from department where id = ?
  2. 根據部門查詢出來的 id(外鍵)胎挎,用于查詢部門對應的多個員工信息:select * from employee where dept_id = ?
  3. 將員工信息關聯到部門信息

先創(chuàng)建一個接口類

public interface DepartmentMapper {
    public Department getDepartmentStep(Integer id);
}

查詢部門 Department 類的配置

<select id="getDepartmentStep" resultMap="empStep">
    select id, depart_name from department where id = #{id}
</select>

查詢員工 Employee 類的配置

<select id="getEmployeeByDeptId" resultType="Employee">
    select id, last_name, gender, email, dept_id from employee where dept_id = #{deptId}
</select>

配置 resultMap沟启,注意 collection 中的 column 屬性對應數據庫中的列名

<resultMap type="Department" id="empStep">
    <!-- Department 類的配置 -->
    <id column="id" property="id"/>
    <result column="depart_name" property="departName"/>
    
    <!-- 
        使用 collection 定義分段的集合類型的屬性 
     -->
    <collection property="employees" 
        select="edu.just.mybatis.dao.EmployeeMapper.getEmployeeByDeptId"
        column="id">
    </collection>
</resultMap>

結果:

[Employee [id=1, lastName=Tom, email=tom@126.com, gender=0, department=null], 
Employee [id=2, lastName=Peter, email=peter@qq.com, gender=1, department=null], 
Employee [id=7, lastName=ljk, email=lkj@123.com, gender=1, department=null], 
Employee [id=15, lastName=lkj, email=lkj@123.com, gender=2, department=null]]


3. 使用延遲加載

collection 標簽中的延遲加載比較簡單,直接在 collection 里面設置 fetchType 屬性值為 lazy 即可
fetchType="lazy" 表示使用延遲加載
fetchType="eager" 表示立即加載

<resultMap type="Department" id="empStep">
    ...
    <collection property="employees" 
        ...
        fetchType="lazy">
    </collection>
</resultMap>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末犹菇,一起剝皮案震驚了整個濱河市德迹,隨后出現的幾起案子,更是在濱河造成了極大的恐慌揭芍,老刑警劉巖胳搞,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異称杨,居然都是意外死亡肌毅,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門姑原,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悬而,“玉大人,你說我怎么就攤上這事锭汛”康欤” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵唤殴,是天一觀的道長般婆。 經常有香客問我,道長眨八,這世上最難降的妖魔是什么腺兴? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮廉侧,結果婚禮上,老公的妹妹穿的比我還像新娘篓足。我一直安慰自己段誊,他們只是感情好,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布栈拖。 她就那樣靜靜地躺著连舍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪涩哟。 梳的紋絲不亂的頭發(fā)上索赏,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天盼玄,我揣著相機與錄音,去河邊找鬼潜腻。 笑死埃儿,一個胖子當著我的面吹牛,可吹牛的內容都是我干的融涣。 我是一名探鬼主播童番,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼威鹿!你這毒婦竟也來了剃斧?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤忽你,失蹤者是張志新(化名)和其女友劉穎幼东,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體科雳,經...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡根蟹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了炸渡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娜亿。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蚌堵,靈堂內的尸體忽然破棺而出买决,到底是詐尸還是另有隱情,我是刑警寧澤吼畏,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布督赤,位于F島的核電站,受9級特大地震影響泻蚊,放射性物質發(fā)生泄漏躲舌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一性雄、第九天 我趴在偏房一處隱蔽的房頂上張望没卸。 院中可真熱鬧,春花似錦秒旋、人聲如沸约计。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽煤蚌。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尉桩,已是汗流浹背筒占。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蜘犁,地道東北人翰苫。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像沽瘦,于是被迫代替她去往敵國和親革骨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355