iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
1
Modern Web

站在Web前端人員角度,學習 Spring Boot 後端開發系列 第 27

Day 27 - Spring Boot @ManyToMany多對多查詢

今天要新增TAG 的資料表儲存了有關於代辦事項的tag,所以TODO對TAG的資料表是多對多的關係,一個代辦事項可以有[生活]、[健康]等多個tag,一個tag也可以對應到很多則代辦事項。多對多對應,可以藉由一個中介表格來完成,使用@ManyToMany的標註

https://ithelp.ithome.com.tw/upload/images/20201006/20118857eumWYS3ZDz.png

TODO資料表

+------------+---------------+------+-----+---------+
| Field      | Type          | Null | Key | Default |
+------------+---------------+------+-----+---------+
| id         | int           | NO   | PRI |  auto   |
| task       | varchar       | YES  |     |  NULL   |
| status     | int           | NO   |     |   1     |
| create_time| TIMESTAMP     | NO   |     | current |
| update_time| TIMESTAMP     | NO   |     | current |
| user_id    | int           | YES  | FK  |  NULL   |
+------------+---------------+------+-----+---------+

TAG資料表

+------------+---------------+------+-----+---------+
| Field      | Type          | Null | Key | Default |
+------------+---------------+------+-----+---------+
| id         | int           | NO   | PRI |  auto   |
| tag        | varchar       | YES  |     |  NULL   |
+------------+---------------+------+-----+---------+

TODOS_TAG 中介資料表

+------------+---------------+------+-----+---------+
| Field      | Type          | Null | Key | Default |
+------------+---------------+------+-----+---------+
| todo_id    | int           | NO   |     |   NULL  |
| tag_id     | int           | NO   |     |  NULL   |
+------------+---------------+------+-----+---------+

在TODO的Entity 增加@ManyToMany的標註。

@JoinTable(name="todos_tag")連結創造一個中介表格(todos_tag)。
joinColumns = {@JoinColumn(name="tag_id")},連接關聯外鍵(tag_id)至TAG的id。
inverseJoinColumns= {@JoinColumn(name="todo_id")},連結到外鍵(todo_id)至TODO的id。

@Entity
@Table
@Data
public class Todo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    @Column
    String task = "";

    @Column(insertable = false, columnDefinition = "int default 1")
    Integer status = 1;

    @CreatedDate
    @Column(updatable = false, nullable = false)
    Date createTime = new Date();

    @LastModifiedDate
    @Column(nullable = false)
    Date updateTime = new Date();

    @JsonBackReference
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="user_id")
    private User user;
    
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="todos_tag", joinColumns = {@JoinColumn(name="tag_id")}, inverseJoinColumns = {@JoinColumn(name="todo_id")})
    Set<Tag> tags;
}

在TAG的Entity 增加@ManyToMany的標註

mappedBy屬性設定了雙向關聯至tags哪裡

@Entity
@Table
public class Tag {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    @Column
    public String tag;

    @ManyToMany(cascade=CascadeType.ALL, mappedBy="tags")
    Set<Todo> todos;
}

接著,來試一下此關聯是否成功,

打開資料庫UI介面時,發現有一個TODOS_TAG的中介表格,接著插入TODO的資料與TAG的資料,並插入TODOS_TAG的一筆關聯資料,
https://ithelp.ithome.com.tw/upload/images/20201006/20118857Hp6SnqwPhy.png

INSERT INTO USER (NAME, GENDER) VALUES ('caili', 2);
INSERT INTO TAG (TAG) VALUES ('生活');
INSERT INTO TODO (TASK, STATUS, UPDATE_TIME, CREATE_TIME, USER_ID) values ('寫鐵人賽', 1, '2020-09-09 17: 00', '2020-09-09 17: 00', 1);

INSERT INTO TODOS_TAG (TODO_ID, TAG_ID) values(1, 1) // 關聯TODO與TAG

接著到我們昨天寫的http://localhost:9100/api/users/1/todos 查看user 1 的代辦事項有哪些並且得知代辦事項有哪些tags。
https://ithelp.ithome.com.tw/upload/images/20201006/20118857eda9iH1JJx.png


上一篇
Day 26 - Spring Boot @OneToMany X @ManyToOne 資料庫關聯
下一篇
Day 28 - Spring Boot Security 守護安全
系列文
站在Web前端人員角度,學習 Spring Boot 後端開發30

尚未有邦友留言

立即登入留言