首頁 > 軟體

MyBatis 實現多對多中間表插入資料

2022-02-28 10:00:13

多對多中間表插入資料

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

所以現在的問題就是怎麼知道這個user_id,再怎麼拿出來,再插入中間表user_role。

方法

在MyBatis中要用到insert和update元素下的3個屬性:

  • useGeneratedKeys (僅對 insert 和 update 有用)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由資料庫內部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關聯式資料庫管理系統的自動遞增欄位),預設值:false。
  • keyProperty (僅對 insert 和 update 有用)唯一標記一個屬性,MyBatis 會通過 getGeneratedKeys 的返回值或者通過 insert 語句的 selectKey 子元素設定它的鍵值,預設:unset。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。
  • keyColumn (僅對 insert 和 update 有用)通過生成的鍵值設定表中的列名,這個設定僅在某些資料庫(像 PostgreSQL)是必須的,當主鍵列不是表中的第一列的時候需要設定。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。

具體實現

1.插入user表,可以看到我們並沒有插入user_id這個屬性,因為是自增的。

<insert id="insert" useGeneratedKeys="true" keyProperty="user_id" keyColumn="user_id">
        insert into user
        (user_name,user_gender,user_email,user_phone,user_address,user_birthday,department_id)
        values(#{user_name},#{user_gender},#{user_email},#{user_phone},#{user_address},#{user_birthday},#{department_id})
    </insert>

2.重點是中間表user_role ,可以看到,我們直接就使用user下面的user_id了,我們也沒有做查詢操作,所以我們並不知曉它的具體值。

<insert id="insertUserRole">
        insert into user_role values(#{user.user_id},#{role.role_id})
    </insert>

3.test類,為了方便大家更好的理解,我們可以做一次測試。

通過下面程式碼可以看到:我們在插入user後,就能夠把user_id列印出來,再插入到中間表中,並沒做其他諸如查詢的操作。

Date date = new Date();
        User user = new User("mike33", "male", "axxxx@163.com", "183xxxxxxxx", "chengdu", date, 1);
        Role role = new Role();
        role.setRole_id(4);
        //插入user
        service.insert(user);
        //列印user_id
        System.out.println("user_id----->>>>" + user.getUser_id());
        //插入中間表
        service.insertUserRole(user, role);

結果:可以看到我們直接插入後,就能取得user_id了,然後再插入中間表,這就解決了這個問題。

當然由於插入一個新的user,必須同時滿足user和role的對映,所以這裡使用Spring transaction來保證這個插入過程的完整性。

使用註解方式實現。

@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED)
    public void insertUserRole(User user, Role role) {
        this.insert(user);
        mapper.insertUserRole(user, role);
    }

多對多的關聯表中,如何同時插入資料的學習心得

今天在寫學校的實訓專案時,遇到如下問題,一個實體類與另一個實體類是多對多的關係,且有個實體類中所儲存的是另一個實體類的集合,所以在進行插入操作是,要同時向兩張表中插入資料,現在已經得到解決辦法。

Student類:

    public class Student implements Serializable {
        private Integer id;
        private String name;
        private Integer age;
        private String bir;
        private String phone;
        private String qq;
        private String attr;
        private String starts;
        private String mark;
        private Integer cityId;
        private Integer clazzId;
        private Integer groupId;
        private String cityName;
        private String clazzName;
        private String groupName;
        private List<Tag> tagList;
    }

Tag表: 

public class Tag implements Serializable {
    private Integer id;
    private String name;
    private String type;
    private Date createtime;
}

有如下需求,在插入學生時,學生會有很多的標籤(tag),在頁面傳回資料是,用了一個tagList集合來接收,現在要將學生的資訊插入到學生表中,然後將學生的標籤放在另一張關聯表中。

插入步驟

步驟一:

先插入學生資訊:

<insert id="save" useGeneratedKeys="true" keyProperty="id" keyColumn="id" >
    insert into t_student(name, age, bir, phone, qq, attr, starts, mark, cityid, clazzid, groupid) values(#{name}, #{age}, #{bir},#{phone},#{qq},#{attr},#{starts},#{mark},#{cityId},#{clazzId},#{groupId})
</insert>
// useGeneratedKeys 是否以jdbc的方式將插入後的自增主鍵又返回個實體類
// keyProperty 實體類中對應的主鍵屬性名
// keyCloumn 資料庫中對應的主鍵屬性名

2.插入關聯表資料

<insert id="saveStudentTag" parameterType="com.lbw.ems.entity.Student">
        insert into t_student_tag(studentid, tagid) values
        <foreach collection="tagList" item="tag" separator=",">
            (#{id}, #{tag.id})
        </foreach>
    </insert>
// 因為此時我們需要當前的學生的Id,所以我們的引數型別還是一個Student類,在插入是,我們需要的是Student類中tagList集合中所有的id
所以使用了foreach標籤
// foreach標籤 遍歷array、list、map(我只用過list)
// collection 填你想要遍歷的集合在實體類中對應的屬性名
// item 將每次遍歷出來的物件取一個名字,不然不好取值,尤其是在兩個實體類的欄位名相同的時候,真的難頂
// sparator="," 每遍歷一次後,在後面加上你所填的符

結果測試

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


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