1. 程式人生 > 實用技巧 >MyBatis 高階查詢之一對多查詢(十)

MyBatis 高階查詢之一對多查詢(十)

高階查詢之一對多查詢

查詢條件:根據遊戲名稱,查詢遊戲賬號資訊

我們在之前建立的對映器介面 GameMapper.java 中新增介面方法,如下:

		/**
     * 根據遊戲名查詢遊戲賬號
     * @param name 遊戲名
     * @return 遊戲實體類
     */
    public GameEntity selectGameByName(String name);

接下來,我分別演示關聯查詢和子查詢方式實現介面方法的對映。

關聯查詢方式

現在我們暫時先拋開 MyBatis 框架,直接從資料庫出發寫一寫關聯查詢的 SQL 語句,如下:

select g.*,a.* from tb_game as g join tb_account as a on g.id=a.game_id where g.name ='英雄聯盟'

我們在資料庫中執行這條 SQL 語句,結果如下:

現在,我們回到 MyBatis 框架,看一下在 XML 對映檔案中,如何實現關聯查詢對映。

首先,我們需要建立 GameEntity 實體類與 AccountEntity 實體類之間的關聯關係,如下:

public class GameEntity {
    private int id;
    private String name;
    private String type;
    private String operator;
    private List<AccountEntity> accounts; //關聯引用遊戲賬號集合
}

這樣,通過遊戲名查詢的賬號資訊就可以對映到 accounts 屬性中。注意 accounts 屬性的 get 和 set 方法要記得新增上去,還有 toString 方法要重寫一下,新增 accounts 屬性的列印資訊。

你可能有疑惑,這裡為何要使用 List 集合呢?原因是一款遊戲對應的賬號資訊可能有多個,而 MyBatis 可以通過使用 resultMap 的 collection 標記將關聯查詢的多條記錄對映到一個 List 集合屬性中。

現在,我們來編寫對映檔案中 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="mapper.GameMapper">
    <resultMap id="gameResultMap" type="entity.GameEntity">
        <id property="id" column="id" />
        <result property="name" column="name" />
        <result property="type" column="type" />
        <result property="operator" column="operator" />
      
       <!-- collection:一對多對映,關聯當前分類下產品資訊 
					  property:對映集合結果
					  ofType:結果集型別 -->
        <collection property="accounts" ofType="entity.AccountEntity">
            <id property="id" column="id" />
            <result property="userName" column="user_name" />
            <result property="password" column="password" />
        </collection>
    </resultMap>
    <select id="selectGameByName" resultMap="gameResultMap">
        select g.*,a.* from tb_game as g join tb_account as a on g.id=a.game_id where g.name =#{name}
    </select>
</mapper>

以上和一對一關聯查詢相比,association 標記改為 collection 標記,表示是一對多對映;javaType 屬性改為ofType 屬性,表示集合裡的元素型別。除此以外,和一對一關聯查詢差不多。

最後,我們在 MyBatisTest 中新增一個單元測試方法,如下:

		@Test
    public void selectGameByNameTest() {
        GameEntity gameEntity = gameMapper.selectGameByName("英雄聯盟");
        System.out.println(gameEntity);

        Assert.assertNotNull(gameEntity);
    }

執行單元測試方法,結果如下:

2020-07-15 18:34:05,260 [main] [mapper.GameMapper.selectGameByName]-[DEBUG] ==>  Preparing: select g.*,a.* from tb_game as g join tb_account as a on g.id=a.game_id where g.name =? 
2020-07-15 18:34:05,307 [main] [mapper.GameMapper.selectGameByName]-[DEBUG] ==> Parameters: 英雄聯盟(String)
2020-07-15 18:34:05,354 [main] [mapper.GameMapper.selectGameByName]-[DEBUG] <==      Total: 2
GameEntity{id=1, name='英雄聯盟', type='MOBA', operator='騰訊遊戲', accounts=[AccountEntity{id=1, userName='瀟灑哥', password='12345'}, AccountEntity{id=4, userName='進擊巨人', password='11111'}]}