MyBatis 高階查詢之一對多查詢(十)
阿新 • • 發佈:2020-10-09
高階查詢之一對多查詢
查詢條件:根據遊戲名稱,查詢遊戲賬號資訊
我們在之前建立的對映器介面 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'}]}