首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate Annotations 維護多對多關聯實戰心得

     編輯:Java 相關知識

核心註解對照

註解屬性說明
@ManyToManytargetEntity被關聯端實體類
cascadePERSIST, MERGE 等,對應 XML cascade
fetchLAZY(預設)或 EAGER
mappedBy被關聯端屬性名(非擁有端必填)
@JoinTablename關聯表名
joinColumns擁有端外鍵欄位
inverseJoinColumns被關聯端外鍵欄位
@Cacheusage緩存策略(READ_WRITE, NONSTRICT_READ_WRITE)

雙向關聯範例:Theater(擁有端)↔ Audience(被關聯端)

擁有端:Theater

@Entity
@Table(name = "THEATER")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Theater implements Serializable {
    @ManyToMany(
        targetEntity = Audience.class,
        cascade = {CascadeType.PERSIST, CascadeType.MERGE},
        fetch = FetchType.LAZY
    )
    @JoinTable(
        name = "THEATER_AUDIENCE",
        joinColumns = @JoinColumn(name = "THEATER_ID"),
        inverseJoinColumns = @JoinColumn(name = "AUDIENCE_ID")
    )
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private List<Audience> audiences = new ArrayList<Audience>();

    // getter/setter 略
}

被關聯端:Audience

@Entity
@Table(name = "AUDIENCE")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Audience implements Serializable {
    @ManyToMany(
        cascade = {CascadeType.PERSIST, CascadeType.MERGE},
        mappedBy = "audiences"   // 綁定擁有端屬性名
    )
    private List<Theater> theaters = new ArrayList<Theater>();

    // getter/setter 略
}

操作關鍵:雙向同步與清理

public void selectWatchers() {
    Theater theater = findTheaterById("showMax");
    theater.getAudiences().clear();           // 1. 清空舊關聯(關鍵步驟)

    List<Audience> list = findAudiencesByMovie("transformers");
    for (Audience a : list) {
        a.getTheaters().add(theater);         // 2. 被關聯端加入
        theater.getAudiences().add(a);        // 3. 擁有端加入
    }
    doSaveEntity(theater);                    // 4. 持久化擁有端
}

避坑指南

  • 必須清空再重建:直接 add 會導致關聯表殘留舊記錄,拋出唯一約束異常或產生髒數據。
  • 只持久化擁有端:mappedBy 端不維護關聯表,save(theater) 即可級聯更新關聯表。
  • 緩存策略區分:集合緩存建議 NONSTRICT_READ_WRITE,實體緩存用 READ_WRITE。
  • FetchType.LAZY 為預設,避免誤觸發全量載入;需即時使用時可在 HQL 中 join fetch。

總結

Annotations 方式比 XML 更直觀、編譯期檢查更強。掌握「擁有端負責關聯表維護、被關聯端只需 mappedBy、雙向同步必清空再建」三原則,即可輕鬆駕馭多對多關聯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved