首頁 > 軟體

Mybatis resultMap標籤繼承、複用、巢狀方式

2022-03-10 16:00:24

resultMap標籤繼承、複用、巢狀

記錄演示 Mybatis 中 resultMap 標籤繼承、複用(包括跨檔案)以及多層巢狀的使用方法,

  • 繼承: 繼承已存在的 resultMap 標籤進行擴充套件
  • 複用: 跨mapper檔案參照現存的 resultMap 標籤
  • 巢狀: 多層巢狀的JavaBean與 resultMap 對映方法

定義表與實體類

建立三個表 group member score

score 與 member 一對一,通過 score.id 關聯

group 與 member 一對多,通過 group.id 關聯

create table `score` (
    `id` int comment '主鍵',
    `math` float comment '數學成績',
    `history` float comment '歷史成績',
    primary key (`id`)
)
create table `member` (
    `id` int comment '主鍵',
    `name` varchar comment '姓名',
    `group_id` int comment '所屬組group表id',
    `score_id` int comment '成績Score表id',
    primary key (`id`)
)
create table `group` (
    `id` int comment '主鍵',
    `name` varchar comment '組名',
    primary key (`id`)
)

實體類

建立三個實體類 Group Member Score

Score 類的物件是 Member 類的成員變數

Member 類的物件集合是 Group 類的成員變數

/** 成績類 */
public class Score {
    private Integer id;
    /** 數學成績 */
    private Float math;
    /** 歷史成績 */
    private Float hitory;
    ...getter And setter...
}
/** 成員類 */
public class Member {
    private Integer id;
    /** 姓名 */
    private String name;
    /** 分數物件 */
    private Score score;
    ...getter And setter...
}
/** 組類 */
public class Group {
    private Integer id;
    /** 組名 */
    private String groupName;
    /** 成員 */
    private List<Member> members;
    ...getter And setter...
}

定義與表對映的 resultMap

在 BeanMapper.xml 定義最基本的與資料庫表欄位對映的 resultMap 標籤

<?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="com.example.BeanMapper">
    <!-- Score實體類對映 -->
    <resultMap id="scoreMap" type="com.example.Score">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="math" jdbcType="FLOAT" property="math" />
        <result column="history" jdbcType="FLOAT" property="history" />
    </resultMap>
    <!-- Member實體類對映 -->
    <resultMap id="memberMap" type="com.example.Member">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="name" jdbcType="VARCHAR" property="name" />
    </resultMap>
    <!-- Group實體類對映 -->
    <resultMap id="groupMap" type="com.example.Group">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="name" jdbcType="VARCHAR" property="groupName" />
    </resultMap>
</mapper>

繼承、複用、巢狀

建立 DemoMapper.xml,演示標籤的繼承、複用、巢狀

複用現存標籤時若位於相同mapper檔案可直接使用 resultMap 的 id 屬性參照,跨檔案時需要指定 namespace 屬性才可正常參照

  • extends: 繼承,可繼承其他 resultMap 並加以擴充套件
  • association: 複用現存的 resultMap,適用於對應的屬性為單JavaBean時,使用 javaType 指定Java型別
  • collection: 複用現存的 resultMap,適用於對應的屬性為JavaBean集合時,使用 ofType 指定Java型別
  • columnPrefix: 只將該屬性指定字首的屬性賦值給當前 resultMap,存在多層巢狀時每進入一層就會將本層字首擷取掉。

如下面的mapper檔案中,外層的 fullMemberMap 字首為 member_,經本次篩選 member_score_id -> score_id,

內層的 scoreMap 字首為 score_,經本次篩選 score_id -> id,最終被賦值給 Score.id

所以只有形如 member_score_id 的欄位才會最終進入 scoreMap 的取值範圍中

若是不復用只是單純巢狀,則可以直接將三個類寫在一個 resultMap 標籤內實現

<?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="com.example.DemoMapper">
    <!-- extends: 繼承 -->
    <resultMap id="fullMemberMap" extends="com.example.BeanMapper.memberMap" type="com.example.Member">
        <!-- association: 複用已存在的resultMap,單JavaBean屬性時使用
                        使用javaType屬性指定JavaBean的型別
                        跨檔案參照需指定namespace -->
        <!-- columnPrefix: 只從 score_ 開頭的欄位為當前resultMap取值 -->
        <association  property="score" resultMap="com.example.BeanMapper.scoreMap" javaType="com.example.Score" columnPrefix="score_" />
    </resultMap>
    
    <resultMap id="fullGroupMap" extends="com.example.BeanMapper.groupMap" type="com.example.Group">
        <!-- collection: 複用已存在的resultMap,JavaBean集合屬性時使用
                        使用ofType屬性指定JavaBean的型別
                        同檔案參照無需指定namespace -->
        <!-- columnPrefix: 只從 member_ 開頭的欄位為當前resultMap取值
                        進入fullMemberMap內巢狀的scoreMap時字首 member_ 會被去除,即 member_score_id 欄位才能被scoreMap正確接收 -->
        <collection property="members" ofType="com.example.Member" resultMap="fullMemberMap" columnPrefix="member_"/>
    </resultMap>
    <!-- 直接參照最終的resultMap,並根據columnPrefix屬性設定的字首為各個欄位指定不同的別名 -->
    <select id="selectGroupById" parameterType="java.lang.Integer" resultMap="fullGroupMap">
        select g.id, g.name,
               m.id member_id, m.name member_name,
               s.id member_score_id, s.math member_score_math, s.history member_score_history
          from `group` g
            left join `member` m on m.group_id = g.id
            left join `score` s on s.id = m.score_id
          where g.id = #{id,jdbcType=INTEGER}
    </select>
</mapper>

使用resultMap需要注意的地方

今天主要還是根據需求在進行sql的編寫 ,在mybatis裡面進行復查和複用的時候一定要去看所對應的有沒有這個類 ,今天弄了幾個dto,還有時間戳的轉換,java裡面的時間戳是以毫秒來進行計算的。

所以說在專用mysql的時候要注意

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com