MyBatis 多對多 中間表插入數據,添加記錄後獲取主鍵ID

目錄

1、需求內容

2、實現方法

2.1 方法

2.2 含義

3、具體實現

3.1 在settings元素中設置

3.2 在xml映射器中配置

3.3 在接口映射器中設置


1、需求內容

有一個很常見的需求,即添加記錄後獲取添加後的主鍵ID,特別是在一次前端調用中需要插入多個表的場景。除了添加單條記錄時獲取主鍵值,有時候可能需要獲取批量添加記錄時各記錄的主鍵值,MyBatis從3.3.1版本開始支持批量添加記錄並返回各記錄主鍵字段值。

比如我在做這個員工管理系統的時候,由於user和role是多對多關係,且user主鍵是自增的,所有我們沒辦法提前知曉這個user_id,所以插入的時候,就需要先插入user,然後再找到剛插入的id拿出來,再插入中間表user_role,這樣才能將表關係對應起來,才能算一個完整的插入的過程。

問題是對於剛剛插入到數據庫中的一條記錄,我怎麼知道這個user_id,再怎麼拿出來,再插入中間表user_role。(當然一種做法是,執行完一條插入數據後,再執行查詢的操作,不推薦這種方法),其實如果用的是MyBatis框架,本身就有這個功能。

2、實現方法

2.1 方法

在MyBatis中要用到insert和update元素下的3個屬性:分別是useGeneratedKeys,keyPropertykeyColumn。這三個屬性(僅對 insert 語句和 update語句 有用)。

2.2 含義

useGeneratedKeys這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數據庫內部生成的主鍵,默認值:false。如果將useGeneratedKeys設置爲true,在執行添加記錄之後可以獲取到數據庫自動生成的主鍵ID。
keyProperty唯一標記一個屬性,MyBatis 會通過 getGeneratedKeys 的返回值或者通過 insert 語句的 selectKey 子元素設置它的鍵值,默認:unset。對應它的值是Java對象中的屬性值。
keyColumn:通過生成的鍵值設置表中的列名,這個設置僅在某些數據庫(像 PostgreSQL)是必須的,當主鍵列不是表中的第一列的時候需要設置。對應它的值是數據庫中表的字段值。

3、具體實現

在MyBatis中,允許設置名稱爲“useGeneratedKeys”參數存在3個位置:

1、在settings元素中設置useGeneratedKeys參數

2、在xml映射器中設置useGeneratedKeys參數

3、在接口映射器中設置useGeneratedKeys參數

在不同位置設置的useGeneratedKeys參數,最終結果相同,但是影響範圍不同。

3.1 在settings元素中設置

在settings元素中設置useGeneratedKeys參數

在settings元素中設置useGeneratedKeys是一個全局參數,但是隻會對接口映射器產生影響,對xml映射器不起效。

<settings>
    <!-- 允許JDBC支持自動生成主鍵,需要驅動兼容。 如果設置爲true則這個設置強制使用自動生成主鍵,
         儘管一些驅動不能兼容但仍可正常工作(比如 Derby)。 -->
    <setting name="useGeneratedKeys" value="true" />
</settings>

此時,在接口映射中添加記錄之後將返回主鍵ID。

public interface TacticsMapper {
    // 受全局useGeneratedKeys參數控制,添加記錄之後將返回主鍵id
    @Insert("insert into op_tactics_info (name,remark, create_time,update_time) values (#{name},#{remark},#{createTime},#{updateTime})")
    Integer insertTactics(Tactics tactics);
}

但是,請注意如果此時在接口映射器中又明確設置了useGeneratedKeys參數,那麼註解映射器中的useGeneratedKeys參數值將覆蓋settings元素中設置的全局useGeneratedKeys參數值。

例如:先在settings元素中設置全局useGeneratedKeys參數值爲true,再在接口映射器中設置useGeneratedKeys參數值爲false,添加記錄之後將不能返回註解ID。 

public interface TacticsMapper {
    // 在接口映射器中設置的useGeneratedKeys參數值將會覆蓋在settings元素中設置全局useGeneratedKeys參數值
    @Options(useGeneratedKeys = false, keyProperty = "id", keyColumn = "id")
    @Insert("insert into op_tactics_info (name,remark, create_time,update_time) values (#{name},#{remark},#{createTime},#{updateTime})")
    Integer insertTactics(Tactics tactics);
}

另外,在settings元素中設置的全局useGeneratedKeys參數對於xml映射器無效。如果希望在xml映射器中執行添加記錄之後返回主鍵ID,則必須在xml映射器中明確設置useGeneratedKeys參數值爲true。

3.2 在xml映射器中配置

在xml映射器中配置useGeneratedKeys參數

<insert id="insertTactics" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
    insert into op_tactics_info
    (tactics_name,remark, create_time,update_time)
    values
    (#{tacticsName},#{remark},#{createTime},#{updateTime})
</insert>

 xml映射器中配置的useGeneratedKeys參數只會對xml映射器產生影響,且在settings元素中設置的全局useGeneratedKeys參數值對於xml映射器不產生任何作用。

3.3 在接口映射器中設置

在接口映射器中設置useGeneratedKeys參數

    // 設置useGeneratedKeys爲true,返回數據庫自動生成的記錄主鍵id
    @Options(useGeneratedKeys = false, keyProperty = "id", keyColumn = "id")
    @Insert("insert into op_tactics_info (name,remark, create_time,update_time) values (#{name},#{remark},#{createTime},#{updateTime})")
    Integer insertTactics(Tactics tactics);

 注意: 在接口映射器中設置的useGeneratedKeys參數會覆蓋在<settings>元素中設置的對應參數值。

【參考資料】

1、深入淺出mybatis之useGeneratedKeys參數用法

2、MyBatis 多對多 中間表插入數據

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章