一對多 1 : N
一對多關聯可以看到,products 和 reviews 這兩張表的關係,一個商品會有多則評論,所以設計上會在 reviews 裡面紀錄 product_id 來關聯回去 products。會應用到 @OneToMany
@ManyToOne
這兩種註解來根據你是哪一方進行關聯。
建立父實體 reviews,標記 @ManyToOne
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Entity @Data @Table(name = "reviews") @JsonIgnoreProperties({"product"}) public class Review { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String comment; private int rating;
@ManyToOne @JoinColumn(name = "product_id", referencedColumnName = "id") private Product product; }
|
注意 reviews 是多的那邊所以用 @ManyToOne
,和一對一配置相同,如果是父實體就會用上 @JoinColumn 並且標出 FK 的欄位。
建立子實體 products,標記 @OneToMany
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Entity @Data @Table(name = "products")
public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String name; private Double price; private String description;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "product_detail_id", referencedColumnName = "id") private ProductDetails productDetails;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "product") private List<Review> reviews; }
|
這邊也配置雙向關聯回去,但是要記得使用 @JsonIgnoreProperties 來指定某些屬性不要序列化成 Json 避免雙向循環,假設你是純粹要把關聯用再查 Review 時可以帶出關聯的 Product 就可以不用在 Product 的 Entity 寫 @OneToMany 的部分,但如果要從 Product 關聯回去 Review 就必須兩邊都綁定,因為 Product 在這邊屬於被子實體,要 mappedBy 確定父實體的關聯屬性,沒辦法單方向關聯回去。
這邊我們讓 Product 可以關聯回去 Review 所以可以查到下面這樣
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| [ { "id": 1, "name": "最後生還者", "price": 59.99, "description": "由 Naughty Dog 開發的動作冒險遊戲。", "productDetails": { "id": 1, "developer": "Naughty Dog", "publisher": "Sony Interactive Entertainment", "releaseDate": "2013-06-14", "languageSupport": "English, Japanese, Chinese" }, "reviews": [ { "id": 1, "comment": "這是一款令人驚嘆的遊戲,擁有引人入勝的故事和令人驚嘆的視覺效果!", "rating": 5 }, { "id": 11, "comment": "遊戲不錯,但希望戰鬥系統能更具挑戰性。", "rating": 4 }, { "id": 12, "comment": "每一秒鐘都充滿樂趣,真的是一款精緻的遊戲!", "rating": 5 } ] }, { "id": 2, "name": "巫師3", "price": 49.99, "description": "由 CD Projekt Red 開發的開放世界角色扮演遊戲。", "productDetails": { "id": 2, "developer": "CD Projekt Red", "publisher": "CD Projekt", "releaseDate": "2015-05-19", "languageSupport": "English, Chinese, Polish" }, "reviews": [ { "id": 2, "comment": "很棒的遊戲,但某些部分的節奏感覺有點慢。", "rating": 4 }, { "id": 13, "comment": "畫質很好,但劇情有點單調。", "rating": 3 } ] } ]
|
關於一對多的設置上其實跟一對一很類似,主要都是要區別出哪個是父實體和子實體,一開始規劃資料表時就可以根據此來配置關聯的欄位,實際撈取資料上也要根據需求決定是否需要雙向關聯,回傳的資料上也可以採用 DTO 的方式可以回傳需要的欄位,中間實作上也要避免雙向循環,這樣就可以好好應用這些關聯方式,下一篇來介紹多對多的部分。
Ref: