
一對多 1 : N
一對多關聯可以看到,products 和 reviews 這兩張表的關係,一個商品會有多則評論,所以設計上會在 reviews 裡面紀錄 product_id 來關聯回去 products。會應用到 @OneToMany @ManyToOne 這兩種註解來根據你是哪一方進行關聯。
建立父實體 reviews,標記 @ManyToOne
| 12
 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
| 12
 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 所以可以查到下面這樣
| 12
 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: