Spring boot data JPA數據庫映射關系 : @OneToOne,@OneToMany,@ManyToMany


問題描述

在利用Spring boot data JPA進行表設計的時候,表對象之間經常存在各種映射關系,如何正確將理解的映射關系轉化為代碼中的映射關系是關鍵之處。

解決辦法

概念理解

  • 舉例:在公司的權限管理中,存在公司表、部門表、員工表。

    1. 公司表和部門表的關系:
      主控方:部門表
      被控方:公司表
    2. 部門表和員工表的關系:
      由於是多對多的關系,不存在誰是主控方或被控方,兩者處於平行關系。
  • 一對多或多對一,用外鍵關聯,若未設置級聯刪除,則刪除被控方記錄的時候會有外鍵約束。

  • 多對多,用中間表關聯,刪除中間表的記錄,不會各方的表造成影響。
  • 在該四個注解中,都含有屬性可設置,以下舉例兩個屬性。
    1. fetch=FetchType.LAZY為默認的數據延遲加載,fetch=FetchType.EAGER為急加載。
    2. cascade={CascadeType.PERSIST,CascadeType.MERGE,
      CascadeType.REFRESH,CascadeType.REMOVE}.
      其中:
      CascadeType.PERSIST級聯新增(又稱級聯保存);
      CascadeType.MERGE:級聯合並(級聯更新);
      CascadeType.REMOVE:級聯刪除;
      CascadeType.REFRESH:級聯刷新
      CascadeType.ALL:以上四種都是;
      一般采用CascadeType.MERGE:級聯合並(級聯更新)即可。默認值是均不進行關聯。

@OneToOne

  • 在一對一的關系中,只需在主控方(數據總表)內注明@OneToOne,而被控方(員工表)只是作為外鍵,不需任何特殊標記。
@Entity
@Table(name = "costume_all_id")
public class AllId extends AbstractEntity {
    private static final long serialVersionUID = 1L;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "costume_member_fk")
    private Member member;// 用戶表外鍵
}
   
   
  
  
          

@OneToMany和@ManyToOne

  • 公司(組織)表相對於部門表是被控方,只需在被控方寫mappedBy,其值為主控方中引用的外鍵對象的名稱。
@Entity
@Table(name = "costume_organization")
public class Organization extends AbstractEntity {
    private static final long serialVersionUID = 1L;

    @Column(nullable = false, length = 50)
    private String name; // 組織名稱

    @OneToMany(mappedBy = "organization")
    private Set<Department> departmentSet; // 部門集合
}
   
   
  
  
          
  • 部門表相對於公司(組織)表是主控方,在主控方只需寫@ManyToOne即可,其對象名為被控表中mappedBy中的值。
  • 同時需要注意,如果需要將公司表對象或者部門表對象轉為JSON數據的時候,為了防止出現無限循環包含對方,需要在部門表(多的一方)的引用公司表(少的一方)對象的set方法上寫上注解@JsonBackReference
@Entity
@Table(name = "costume_department")
public class Department extends AbstractEntity {
    private static final long serialVersionUID = 1L;

    @Column(nullable = false, length = 50)
    private String name; // 部門名稱

    @ManyToOne(optional = false)
    private Organization organization; // 組織外鍵

    @ManyToMany
    private Set<Member> memberSet; // 用戶表外鍵

    public Organization getOrganization() {
        return organization;
    }

    @JsonBackReference
    public void setOrganization(Organization organization) {
        this.organization = organization;
    }
}
   
   
  
  
          

@ManyToMany

  • 在多對多的情況下,如部門表和員工表之間的關系(暫不去深究一個員工是否能有多個部門的身份)。
  • 部門表和員工表只需在引用對象集合上注明@ManyToMany即可,其中部門表的寫法如上段代碼,員工表的寫法如下段代碼。
  • 在多對多的映射中會生成一張中間表,其表名和字段名均有默認的命名規則,若需指定表名和字段名,只需在兩者的一方或雙方寫上@JoinTable注解即可,詳情如下代碼段,表名屬性name=”table_name”,與joinColumns屬性是同級屬性,即寫在其前即可。
  • 同時需要注意,如果需要將員工表對象或者部門表對象轉為JSON數據的時候,為了防止出現無限循環包含對方,需要在一方的引用對方對象的set方法(Set對象的set方法)上寫上注解@JsonBackReference
@Entity
@Table(name = "costume_member")
public class Member extends AbstractEntity {
    private static final long serialVersionUID = 1L;

    @Column(nullable = false, length = 20)
    private String name;

    @ManyToMany
    @JoinTable(joinColumns = { @JoinColumn(name = "member_id") }, inverseJoinColumns = {
            @JoinColumn(name = "department_id") }) //被控方表字段名
    private Set<Department> departmentSet; // 部門表外鍵

    public Set<Department> getDepartmentSet() {
        return departmentSet;
    }

    @JsonBackReference
    public void setDepartmentSet(Set<Department> departmentSet)
    {
        this.departmentSet = departmentSet;
    }
}
   
   
  
  
          


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM