mybatis如何批量添加一對(duì)多中間表
批量添加一對(duì)多中間表
建立中間表A,一個(gè)id對(duì)應(yīng)多個(gè)lid;
傳入兩條參數(shù)
long id;//單個(gè)數(shù)值 List lid;//集合數(shù)值
dao層語句
int insertb(@Param("id")long id,@Param("lid")List lid);mybatis中的寫法
insert into A(id,lid) values
? ? ? ? <foreach collection="lid" item="data" separator=",">
? ? ? ? ? ? (#{id},#{data})
? ? ? ? </foreach>多對(duì)多條件下插入中間表(使用insert標(biāo)簽的屬性)
說下需求
我的數(shù)據(jù)庫中有兩張表,一張是Blog表,一張是Type表,分別代表了博客和博客類別,它們之間是多對(duì)多關(guān)系,它們由一張中間表blog_type維護(hù)。
(簡(jiǎn)單起見,blog表只有兩個(gè)數(shù)據(jù),id和title。type表只有id和name)

那么需求就是:
現(xiàn)在我想插入一條Blog數(shù)據(jù),因?yàn)閎log和type是多對(duì)多關(guān)系,想插入其中一個(gè)數(shù)據(jù),就得維護(hù)他們之間那個(gè)中間表blog_type的關(guān)系(插入中間表字段)。
解決方案
那么我能想到的解決方案是:
寫兩段insert標(biāo)簽,第一段sql語句插入blog表,第二段sql語句插入insert表:
<insert id="insertBlogWithoutType" parameterType="blog">
insert into t_blog (title)
values (#{title});
</insert>
<insert id="insertBlog_Type">
insert into blog_type (bid, tid) values(#{blog.id},#{type.id})
</insert>
但是這么做會(huì)有它的問題
由于blog表id為自增,所以我并沒有插入id。如何在第二個(gè)insert查詢語句中獲取剛剛插入的id呢?
經(jīng)過多方查找我發(fā)現(xiàn)了解決方案:
要用到MyBatis中insert標(biāo)簽的三個(gè)屬性:
useGeneratedKeys(僅對(duì) insert 和 update 有用)這會(huì)令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數(shù)據(jù)庫內(nèi)部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關(guān)系數(shù)據(jù)庫管理系統(tǒng)的自動(dòng)遞增字段),默認(rèn)值:false。keyProperty(僅對(duì) insert 和 update 有用)唯一標(biāo)記一個(gè)屬性,MyBatis 會(huì)通過 getGeneratedKeys 的返回值或者通過 insert 語句的 selectKey 子元素設(shè)置它的鍵值,默認(rèn):unset。如果希望得到多個(gè)生成的列,也可以是逗號(hào)分隔的屬性名稱列表。keyColumn(僅對(duì) insert 和 update 有用)通過生成的鍵值設(shè)置表中的列名,這個(gè)設(shè)置僅在某些數(shù)據(jù)庫(像 PostgreSQL)是必須的,當(dāng)主鍵列不是表中的第一列的時(shí)候需要設(shè)置。如果希望得到多個(gè)生成的列,也可以是逗號(hào)分隔的屬性名稱列表。
重新生成的代碼如下所示:
<insert id="insertBlogWithoutType" parameterType="blog" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into t_blog (title)
values (#{title});
</insert>
<insert id="insertBlog_Type">
insert into blog_type (bid, tid) values(#{blog.id},#{type.id})
</insert>
注意!keyProperty是Java對(duì)象的屬性名!不是數(shù)據(jù)庫表中字段名!
測(cè)試
編寫Dao層
//分成兩個(gè)方法,但是他們兩個(gè)將在Service層合二為一
int insertBlogWithoutType(Blog blog);
int insertBlog_Type(@Param("blog")Blog blog, @Param("type")Type type);
Dao層就是對(duì)應(yīng)的前面mapper文件里的兩個(gè)方法
Service層
public void insertBlog(Blog blog, List<Type> types) {
blogDao.insertBlogWithoutType(blog);
for (Type type : types) {
blogDao.insertBlog_Type(blog, type);
}
}
這里的意思是,先插入一個(gè)傳進(jìn)來的blog(第一個(gè)參數(shù))。然后插入之后根據(jù)插進(jìn)來的blog的主鍵(blog的id)和傳入的type的主鍵(type的id),插入中間表。
Test類
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BlogService blogServiceImpl = (BlogService) context.getBean("BlogServiceImpl");
//設(shè)置blog
Blog blog = new Blog();
blog.setTitle("【MyBatis】多對(duì)多條件下插入中間表(使用insert標(biāo)簽的屬性)");
//設(shè)置該blog對(duì)應(yīng)的type
List<Type> types = new ArrayList<Type>();
types.add(new Type(1,"數(shù)據(jù)庫"));
types.add(new Type(2,"Debug專題"));
blogServiceImpl.insertBlog(blog, types);
}
可以看到,設(shè)置blog的時(shí)候,并沒有設(shè)置blog的id屬性,但是調(diào)用insertBlog時(shí),插入中間表卻已經(jīng)知道了blog的id屬性。這就是MyBatis中insert標(biāo)簽的三個(gè)屬性的作用了!
執(zhí)行完上面的代碼,數(shù)據(jù)庫里既插入了一條新的blog,又維護(hù)了他們之間那個(gè)中間表blog_type的關(guān)系(插入了中間表),至此問題解決。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java虛擬機(jī)裝載和初始化一個(gè)class類代碼解析
這篇文章的主要內(nèi)容是Java虛擬機(jī)裝載和初始化一個(gè)class類的代碼解析,包括介紹了裝載和初始化的時(shí)機(jī)與方式,需要的朋友可以參考下。2017-09-09
Java線程池隊(duì)列LinkedTransferQueue示例詳解
這篇文章主要為大家介紹了Java線程池隊(duì)列LinkedTransferQueue示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Java實(shí)現(xiàn)將圖片上傳到webapp路徑下 路徑獲取方式
這篇文章主要介紹了Java實(shí)現(xiàn)將圖片上傳到webapp路徑下 路徑獲取方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
JDK1.8源碼下載及idea2021導(dǎo)入jdk1.8源碼的詳細(xì)步驟
這篇文章主要介紹了JDK1.8源碼下載及idea2021導(dǎo)入jdk1.8源碼的詳細(xì)步驟,在文章開頭就給大家分享了JDK1.8源碼下載地址和下載步驟,告訴大家idea2021.1.3導(dǎo)入JDK1.8源碼步驟,需要的朋友可以參考下2022-11-11
java使用監(jiān)聽器實(shí)現(xiàn)一個(gè)統(tǒng)計(jì)網(wǎng)站在線人數(shù)的示例
本文主要介紹了java使用監(jiān)聽器實(shí)現(xiàn)一個(gè)統(tǒng)計(jì)網(wǎng)站在線人數(shù)的示例,具有一定的參考價(jià)值,有需要的朋友可以了解一下。2016-10-10

