MyBatis?實(shí)現(xiàn)多對(duì)多中間表插入數(shù)據(jù)
多對(duì)多中間表插入數(shù)據(jù)
在做這個(gè)員工管理系統(tǒng)demo的時(shí)候,由于user和role是多對(duì)多關(guān)系,且user主鍵是自增的,所有我們沒(méi)辦法提前知曉這個(gè)user_id,所以插入的時(shí)候,就需要先插入user,然后再找到剛插入的id拿出來(lái),再插入中間表user_role,這樣才能將表關(guān)系對(duì)應(yīng)起來(lái),才能算一個(gè)完整的插入的過(guò)程。
所以現(xiàn)在的問(wèn)題就是怎么知道這個(gè)user_id,再怎么拿出來(lái),再插入中間表user_role。
方法
在MyBatis中要用到insert和update元素下的3個(gè)屬性:
useGeneratedKeys(僅對(duì) insert 和 update 有用)這會(huì)令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來(lái)取出由數(shù)據(jù)庫(kù)內(nèi)部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)的自動(dòng)遞增字段),默認(rèn)值:false。keyProperty(僅對(duì) insert 和 update 有用)唯一標(biāo)記一個(gè)屬性,MyBatis 會(huì)通過(guò) getGeneratedKeys 的返回值或者通過(guò) insert 語(yǔ)句的 selectKey 子元素設(shè)置它的鍵值,默認(rèn):unset。如果希望得到多個(gè)生成的列,也可以是逗號(hào)分隔的屬性名稱(chēng)列表。keyColumn(僅對(duì) insert 和 update 有用)通過(guò)生成的鍵值設(shè)置表中的列名,這個(gè)設(shè)置僅在某些數(shù)據(jù)庫(kù)(像 PostgreSQL)是必須的,當(dāng)主鍵列不是表中的第一列的時(shí)候需要設(shè)置。如果希望得到多個(gè)生成的列,也可以是逗號(hào)分隔的屬性名稱(chēng)列表。
具體實(shí)現(xiàn)
1.插入user表,可以看到我們并沒(méi)有插入user_id這個(gè)屬性,因?yàn)槭亲栽龅摹?/p>
<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.重點(diǎn)是中間表user_role ,可以看到,我們直接就使用user下面的user_id了,我們也沒(méi)有做查詢(xún)操作,所以我們并不知曉它的具體值。
<insert id="insertUserRole">
insert into user_role values(#{user.user_id},#{role.role_id})
</insert>3.test類(lèi),為了方便大家更好的理解,我們可以做一次測(cè)試。
通過(guò)下面代碼可以看到:我們?cè)诓迦雞ser后,就能夠把user_id打印出來(lái),再插入到中間表中,并沒(méi)做其他諸如查詢(xún)的操作。
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);結(jié)果:可以看到我們直接插入后,就能取得user_id了,然后再插入中間表,這就解決了這個(gè)問(wèn)題。

當(dāng)然由于插入一個(gè)新的user,必須同時(shí)滿(mǎn)足user和role的映射,所以這里使用Spring transaction來(lái)保證這個(gè)插入過(guò)程的完整性。
使用注解方式實(shí)現(xiàn)。
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED)
public void insertUserRole(User user, Role role) {
this.insert(user);
mapper.insertUserRole(user, role);
}多對(duì)多的關(guān)聯(lián)表中,如何同時(shí)插入數(shù)據(jù)的學(xué)習(xí)心得
今天在寫(xiě)學(xué)校的實(shí)訓(xùn)項(xiàng)目時(shí),遇到如下問(wèn)題,一個(gè)實(shí)體類(lèi)與另一個(gè)實(shí)體類(lèi)是多對(duì)多的關(guān)系,且有個(gè)實(shí)體類(lèi)中所存儲(chǔ)的是另一個(gè)實(shí)體類(lèi)的集合,所以在進(jìn)行插入操作是,要同時(shí)向兩張表中插入數(shù)據(jù),現(xiàn)在已經(jīng)得到解決辦法。
Student類(lèi):
?? ?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;
}有如下需求,在插入學(xué)生時(shí),學(xué)生會(huì)有很多的標(biāo)簽(tag),在頁(yè)面?zhèn)骰財(cái)?shù)據(jù)是,用了一個(gè)tagList集合來(lái)接收,現(xiàn)在要將學(xué)生的信息插入到學(xué)生表中,然后將學(xué)生的標(biāo)簽放在另一張關(guān)聯(lián)表中。
插入步驟
步驟一:
先插入學(xué)生信息:
<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的方式將插入后的自增主鍵又返回個(gè)實(shí)體類(lèi)
// keyProperty 實(shí)體類(lèi)中對(duì)應(yīng)的主鍵屬性名
// keyCloumn 數(shù)據(jù)庫(kù)中對(duì)應(yīng)的主鍵屬性名
2.插入關(guān)聯(lián)表數(shù)據(jù)
<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>
// 因?yàn)榇藭r(shí)我們需要當(dāng)前的學(xué)生的Id,所以我們的參數(shù)類(lèi)型還是一個(gè)Student類(lèi),在插入是,我們需要的是Student類(lèi)中tagList集合中所有的id
所以使用了foreach標(biāo)簽
// foreach標(biāo)簽 遍歷array、list、map(我只用過(guò)list)
// collection 填你想要遍歷的集合在實(shí)體類(lèi)中對(duì)應(yīng)的屬性名
// item 將每次遍歷出來(lái)的對(duì)象取一個(gè)名字,不然不好取值,尤其是在兩個(gè)實(shí)體類(lèi)的字段名相同的時(shí)候,真的難頂
// sparator="," 每遍歷一次后,在后面加上你所填的符
結(jié)果測(cè)試



以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解JSON與?Java對(duì)象之間的轉(zhuǎn)化
在現(xiàn)在的日常開(kāi)發(fā)中,不管前端還是后端,JSON?格式的數(shù)據(jù)是用得比較多的,甚至可以說(shuō)無(wú)處不在。所以本文主要來(lái)講講JSON?格式的數(shù)據(jù)與?Java?對(duì)象之間的轉(zhuǎn)化吧2023-03-03
淺談序列化之protobuf與avro對(duì)比(Java)
下面小編就為大家?guī)?lái)一篇淺談序列化之protobuf與avro對(duì)比(Java)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
SpringBoot2 整合MinIO中間件實(shí)現(xiàn)文件便捷管理功能
這篇文章主要介紹了SpringBoot2 整合MinIO中間件,實(shí)現(xiàn)文件便捷管理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
JAVA Frame 窗體背景圖片,首位相接滾動(dòng)代碼實(shí)例
這篇文章主要介紹了JAVA Frame 窗體背景圖片,首位相接滾動(dòng)代碼示例,需要的朋友可以參考下復(fù)制代碼2017-04-04
SpringBoot集成阿里巴巴Druid監(jiān)控的示例代碼
這篇文章主要介紹了SpringBoot集成阿里巴巴Druid監(jiān)控的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
使用CI/CD工具Github Action發(fā)布jar到Maven中央倉(cāng)庫(kù)的詳細(xì)介紹
今天通過(guò)對(duì)Github Action的簡(jiǎn)單使用來(lái)介紹了CI/CD的作用,這個(gè)技術(shù)體系是項(xiàng)目集成交付的趨勢(shì),也是面試中的一個(gè)亮點(diǎn)技能。 而且這種方式可以實(shí)現(xiàn)“一次配置,隨時(shí)隨地集成部署”,感興趣的朋友一起看看吧2021-07-07
背包問(wèn)題-動(dòng)態(tài)規(guī)劃java實(shí)現(xiàn)的分析與代碼
這篇文章主要給大家介紹了關(guān)于背包問(wèn)題動(dòng)態(tài)規(guī)劃java實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12

