Spring Data JPA
hibernate-core
One to One
搭配 Join Table (關聯表): 如果希望兩個實體擁有各自獨立的主鍵,可以使用此方式。 優點是靈活性高,缺點是需要額外維護一張關聯表。
搭配 Foreign Key (外鍵): 最常見的方式。一個實體的主鍵同時作為指向另一個實體的外鍵。 可以避免額外的關聯表,並建立強連結。
Shared Primary Key (共享主鍵): 兩個實體完全共用同一個主鍵值。 這是最強的一對一映射方式,但靈活性較低。
- 關聯表方式靈活性較佳但效能稍差。
- 在大多數情況下,外鍵方式 (Foreign Key) 是預設的最佳選擇。
- 只有在主鍵必須完全相同時才考慮共享主鍵。
共享主鍵範例 (Shared Primary Key)
- 雙方均標註
@OneToOne,其中一方使用@MapsId。 - 實體類別範例:
- products (父)
- products_details (子,共享父的主鍵)
外鍵方式範例 (One to One with Foreign Key)
Lazy & Eager Load
- Lazy (延遲加載): 只有在真正存取到關聯屬性時,才會發出 SQL 查詢。
- Eager (立即加載): 在查詢主體時,一併透過 Join 獲取關聯資料。
Many to Many
erDiagram
student ||--|{ students_courses : has
course ||--|{ students_courses : has
JPA Entity Life Cycle (生命週期)
- New / Transient: 新建立的物件,尚未擁有主鍵 ID,且未被 Persistence Context 管理。
- Managed: 已持久化且受容器管理,對物件的任何修改都會在事務提交時同步至資料庫。
- Detached: 物件擁有 ID,但已脫離容器管理 (例如事務已結束或手動 detach)。
- Removed: 標記為刪除,會在事務提交時從資料庫移除。
flowchart TB nt[New/Transient] d[Detached] m[Managed] r[Removed] db((database)) nt -->|persist, save| m m -->|detach, evict, clear, close| d m -->|remove| r m -->|flush| db d -->|merge| m r -->|persist| m r -->|flush| db
JPA vs Spring Data JPA vs Hibernate
flowchart LR SDJPA[Spring Data JPA] JPA[JPA] subgraph Hibernate JDBC[JDBC] end DB[Database] SDJPA <--> JPA <--> Hibernate <--> DB
| 項目 | 說明 |
|---|---|
| JPA | 規範 (Specification),定義 ORM 標準。 |
| Hibernate | 實作 (Implementation),JPA 最常用的供應商。 |
| Spring Data JPA | 封裝層,旨在減少 DAO 樣板代碼。 |