【MyBatis】多對多條件下插入中間表(使用insert標簽的屬性)


此文轉載自:https://blog.csdn.net/weixin_44757863/article/details/110010556

需求

我的數據庫中有兩張表,一張是Blog表,一張是Type表,分別代表了博客和博客類別,它們之間是多對多關系,它們由一張中間表blog_type維護。

(簡單起見,blog表只有兩個數據,id和title。type表只有id和name)
在這里插入圖片描述

那么需求就是:
現在我想插入一條Blog數據,因為blog和type是多對多關系,想插入其中一個數據,就得維護他們之間那個中間表blog_type的關系(插入中間表字段)。

解決方案

那么我能想到的解決方案是:

寫兩段insert標簽,第一段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>

但是這么做會有它的問題

由於blog表id為自增,所以我並沒有插入id。如何在第二個insert查詢語句中獲取剛剛插入的id呢?

經過多方查找我發現了解決方案:

要用到MyBatis中insert標簽的三個屬性:
(內容引自
MyBatis 多對多 中間表插入數據

useGeneratedKeys (僅對 insert 和 update 有用)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數據庫內部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關系數據庫管理系統的自動遞增字段),默認值:false。

keyProperty (僅對 insert 和 update 有用)唯一標記一個屬性,MyBatis 會通過 getGeneratedKeys 的返回值或者通過 insert 語句的 selectKey 子元素設置它的鍵值,默認:unset。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。

keyColumn (僅對 insert 和 update 有用)通過生成的鍵值設置表中的列名,這個設置僅在某些數據庫(像 PostgreSQL)是必須的,當主鍵列不是表中的第一列的時候需要設置。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。

重新生成的代碼如下所示:

    <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對象的屬性名!不是數據庫表中字段名!

測試

編寫Dao層

//分成兩個方法,但是他們兩個將在Service層合二為一
    int insertBlogWithoutType(Blog blog);
    int insertBlog_Type(@Param("blog")Blog blog, @Param("type")Type type);

Dao層就是對應的前面mapper文件里的兩個方法

Service層

public void insertBlog(Blog blog, List<Type> types) {
        blogDao.insertBlogWithoutType(blog);
        for (Type type : types) {
            blogDao.insertBlog_Type(blog, type);
        }
    }

這里的意思是,先插入一個傳進來的blog(第一個參數)。然后插入之后根據插進來的blog的主鍵(blog的id)和傳入的type的主鍵(type的id),插入中間表。

Test類

@Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BlogService blogServiceImpl = (BlogService) context.getBean("BlogServiceImpl");

        //設置blog
        Blog blog = new Blog();
        blog.setTitle("【MyBatis】多對多條件下插入中間表(使用insert標簽的屬性)");
        
        //設置該blog對應的type
        List<Type> types = new ArrayList<Type>();
        types.add(new Type(1,"數據庫"));
        types.add(new Type(2,"Debug專題"));

        blogServiceImpl.insertBlog(blog, types);
    }

可以看到,設置blog的時候,並沒有設置blog的id屬性,但是調用insertBlog時,插入中間表卻已經知道了blog的id屬性。這就是MyBatis中insert標簽的三個屬性的作用了!

執行完上面的代碼,數據庫里既插入了一條新的blog,又維護了他們之間那個中間表blog_type的關系(插入了中間表),至此問題解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM