iT邦幫忙

2024 iThome 鐵人賽

DAY 7
1
佛心分享-SideProject30

從卡關到通關的Spring Boot 腦內風暴系列 第 7

不用剪但要理的多角關係—實體關係

  • 分享至 

  • xImage
  •  

程式開發中,不同實體之間的關係就像多角戀,有多對多、一對多等各種複雜關係,但其實只要梳理清楚,就能使結構更加清晰。在物件關係映射(ORM)中,正確處理實體關係是非常重要的,特別是使用JPA(Java Persistence API),掌握不同的實體關係及配置,能夠有效操控資料庫。

實體關係主要分為三種:

一對一關係(One to One)

意指每個實體都只有一個對應的實體。例如,member對應唯一的address,代表每一member只會有一個address,反之亦然。
使用@OneToOne註解定義此一關係:

@Entity
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "address_id", referencedColumnName = "id")
    private Address address;
}

@Entity
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String street;
    private String city;
}

cascade是指定對實體操作時,另一方實體是否會級聯影響:

  • CascadeType.ALL:對Member實體保存、更新或刪除操作時,Address也會相應操作。
  • CascadeType.PERSIST: 只有新增實體時才會級聯。
  • CascadeType.MERGE: 只有更新實體時才會級聯。
  • CascadeType.REMOVE: 只有刪除實體時才會級聯。
  • CascadeType.REFRESH: 只有刷新實體時才會級聯。

一對多關係(One to Many)

表示一個實體擁有多個實體,這些實體屬於同一個實體。例如一個專案底下有多個任務,而這些多個任務共同屬於同一個專案。
使用@OneToMany或@ManyToOne註解定義此一關係:

@Entity
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
    private List<Task> tasks = new ArrayList<>();
}

@Entity
public class Task {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "project_id")
    private Project project;
}

mappedBy是指定在雙向關聯當中,關係的擁有方是誰。
以上例而言,Task實體當中的project是擁有方,因此Project類要使用 mappedBy = "project",這樣讓JPA知道兩者關聯,避免產生多餘的中間表。

多對多關係(Many to Many)

每個實體都可以與多個實體產生關聯,例如tag跟project,每個project可以有多個tag,而每個tag也可以對應多個project。在JPA當中,實現多對多關係,通常需要一個中間關聯表實現。
使用@ManyToMany註解定義此一關係:

@Entity
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToMany
    @JoinTable(
        name = "project_tag",
        joinColumns = @JoinColumn(name = "project_id"),
        inverseJoinColumns = @JoinColumn(name = "tag_id")
    )
    private Set<Tag> tages = new HashSet<>();
}

@Entity
public class Tag {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToMany(mappedBy = "tages")
    private Set<Project> projectes = new HashSet<>();
}

JAP會自動創建project_tag中間表,透過註解產生中間表管理他們之間多對多關係。不用手動處理關聯表。

綜合上述,了解實體的關係是非常重要,能夠維持資料完整性以及擴展性,使用JAP的配置能有效操作資料庫,避免多餘表格產生,使程式運行順利。


上一篇
讓資料庫活起來—Entity 常用標註
下一篇
誤會大了—JPA不是ORM框架
系列文
從卡關到通關的Spring Boot 腦內風暴30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言