操作 Spring Data JPA 需要對於資料表之間的關聯與配置有一定的了解,可以幫助你在規劃資料庫及撈取資料上有很大的幫助。
後續文章會依序介紹常見的幾種關聯操作,若這邊設計一個情境開設一個電商平台,賣電玩的商品,會有一些表紀錄商品的一些資訊,我們可以藉此來探討資料表之間的關聯。主要有下面這幾張表:
關聯時必須知道誰是父實體(或稱維護方,具有 FK 可以關聯被維護 PK),誰是子實體(被維護、被參考對象)
父實體(維護方) | 子實體(被維護方) | |
---|---|---|
關聯 | 具有FK | 被關聯 PK 或其他 |
註解應用區別 | @JoinColumn() | 關聯註解加入參數mappedBy |
級聯配置參數,針對父實體的資料操作,子實體會有對應自動操作
資料讀取配置參數,設定讀取的方式是立即或是特定條件才讀
各類關聯註解預設值參考
Relation | Default |
---|---|
@OneToOne | FetchType.EARGE |
@ManyToOne | FetchType.EARGE |
@OneToMany | FetchType.LAZY |
@ManyToMany | FetchType.LAZY |
一對一的關聯可以從 products 和 product_details 這兩張表之間的關聯看到,一個商品會對應一個詳細資料,要透過 JPA 會用到 @OneToOne
註解來進行關聯,這些關聯註解都有一些參數可以設置。在這邊的範例就是 products 是父實體,product_details 是子實體。
定義父實體 products
@Entity
@Data
@Table(name = "products")
//@JsonIgnoreProperties({"productDetail"}) // 避免循環引用
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
private String description;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "product_detail_id", referencedColumnName = "id")
private ProductDetails productDetails;
}
@JoinColumn 的 name 參數指的是要提供 FK 的欄位名稱,referencedColumnName 是指被關聯方的 關聯欄位(不寫預設是被關聯的主鍵PK)
定義子實體 product_details
@Entity
@Data
@Table(name = "product_details")
@JsonIgnoreProperties("product")
public class ProductDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String developer;
private String publisher;
private String releaseDate;
private String languageSupport;
@OneToOne(mappedBy = "productDetails")
private Product product;
}
這邊需要注意如果需要雙向關聯,這邊也要在關聯要呈現的屬性上面加上 @OneToOne(mappedBy = "{父方映射關聯的欄位}"),這邊也就是指父實體放 @OneToOne 欄位的變數名 productDetails
另外補充如果雙向關聯開啟,就會出現無限循環關聯的問題,你可以想像會出現 product 關聯出 product_details 但裡面又關聯回 product 就會一直永無止境導致回傳資料混亂,有幾個方法可以解決:
實際撈回來的資料
[
{
"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"
}
},
{
"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"
}
},
// 略......
]
以上就是基本一對一的關聯操作,下篇會來介紹一對多 (1 : N) 的操作模式。
這邊想要補充一下推薦有使用 Intellij 的 database UI ,連接好資料庫之後,對資料庫點右鍵選 Diagrams > Show Diagram 他就可以將各欄位之間的關聯狀況畫出來,還可以匯出圖片,就可以不用自己畫 ER 圖了,真的太強大 !!
Ref:
相關文章也會同步更新我的部落格,有興趣也可以在裡面找其他的技術分享跟資訊。