在物件導向的世界裡,類別之間除了繼承關係外,還存在著各種關聯關係:一對一、一對多、多對一以及多對多。這些關係在 Kodo EJB 中的實現原理大同小異,本文將以一對一關聯為核心進行深入解析,並透過實際範例說明如何運用註解定義類別間的關聯,最後簡要說明其餘三種關係的實現方式。
在面向對象領域,類別 A 和類別 B 之間的一對一關係必須滿足兩個條件:物件 A1 參考物件 B1,且類別 A 的其他物件 An 無法參考同一個 B1 物件。在關係型資料庫中,通常透過唯一外鍵來實現一對一關聯。
假設我們要開發一個圖書館管理系統,需要記錄書籍的基本資訊(編號、書名、出版日期)以及書籍的前言、序言等擴充資訊。為了演示需求,我們將書籍設計為 Book 類別(包含編號與書名),將前言資訊設計為 BookExtend 類別(包含編號與前言內容)。因為一本書只有一個前言,且前言專屬於該書,所以兩者自然形成一對一關係。
Kodo EJB 提供 @OneToOne 註解來宣告一對一關係,主要屬性如下:
BookExtend 中也有 Book 屬性),則必須設定此屬性以避免資料一致性問題。PERSIST(新建)、REMOVE(刪除)、REFRESH(刷新)、MERGE(更新)四種類型,或使用 ALL 代表全部。EAGER(立即載入)或 LAZY(延遲載入),預設為 EAGER。false 表示不可為 null,預設為 true。@JoinColumn 用於定義主類別對應資料表中用於關聯的欄位,屬性包括:
@Entity(name = "Book")
@Inheritance(strategy = InheritanceType.JOINED)
public class Book {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
public int id;
@Basic @Column(name = "NAME")
public String name;
@OneToOne(optional = true, cascade = CascadeType.ALL)
@JoinColumn(name = "extendID", referencedColumnName = "ID")
public BookExtend bookExtend;
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class BookExtend {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
public int id;
@Basic @Column(name = "NAME")
public String name;
}
只需持久化 Book 物件,BookExtend 會自動同步新建:
EntityManager em = emf.createEntityManager(PersistenceContextType.EXTENDED);
em.getTransaction().begin();
Book book = new Book();
book.name = "Kodo入門";
BookExtend bookExtend = new BookExtend();
bookExtend.name = "Spring is a very good book that ...";
book.bookExtend = bookExtend;
em.persist(book); // 級聯持久化
em.getTransaction().commit();
同理,呼叫 merge() 或執行刪除查詢時,關聯物件會同步更新或刪除,實現資料一致性維護。
@OneToMany,屬性包括 targetEntity、mappedBy、cascade、fetch。@ManyToOne,屬性包括 targetEntity、cascade、fetch、optional。@ManyToMany,屬性包括 targetEntity、mappedBy、cascade、fetch。這三種關係的屬性含義與 @OneToOne 同名屬性對應,實作邏輯類似,讀者可參考一對一的實現過程自行完成。
本文以一對一關聯為例,結合圖書館管理系統場景,詳細闡述了 Kodo EJB 中透過註解定義類別關聯並實現級聯操作的完整流程。掌握核心註解 @OneToOne、@JoinColumn 及其屬性配置,即可輕鬆處理各類關聯關係,讓持久層開發更加高效優雅。