1. 程式人生 > 程式設計 >解決使用@ManyToMany查詢資料時的死迴圈問題

解決使用@ManyToMany查詢資料時的死迴圈問題

目錄
  • 使用@ManyToMany查詢資料時的死迴圈
    • 一、在Role中加上@onIgnore註解
    • 二、將雙向關聯改為單向關聯
  • 單向多對多@ManyToMany的使用和理解

    使用@ManyToMany查詢資料時的死迴圈

    初學使用spring data jpa,將問題記錄

    以User 和Role為例,兩者為雙向的多對多關係,即可以通過User查詢到Role資訊,也可以通過Role查詢到User資訊

    首先要明白為什麼會出現死迴圈這個問題,造成這個死迴圈的原因是因為查詢User時,包含了Role屬性,Role中又需要查詢除user屬性,這個不是spring data jpa 的問題,而是隻要程式碼裡互相關聯都會造成這種情況,解決這種情況的方法我大概研究出了兩種

    一、在Role中加上www.cppcns.com@JsonIgnore註解

    程式碼如下

    User.

    package com.example.demo.entity;
    import lombok.Data;  
    import javax.persistence.*;
    import java.util.Set;
     
    /**
     * @author lidai
     * @date 2018/10/23 13:53
     */
    @Entity
    @Data
    @Table(name = "t_user")
    public class User {
     
        @Id
        private String userId; 
        private String username; 
        private String password;
     
        @ManyToMany(cascade = CascadeType.ALL,fetch=FetchType.EAGER)
        @JoinTable(name = "t_user_role",joinColumns = @JoinColumn(name = "user_id",referencedColumnName = "user_id"),inverseJoinColumns = @JoinColumn(name = "role_id",referencedColumnName = "role_id"))
        private Set<Role> roleSet;  
    }

    Role.java

    package com.example.demo.entity; 
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import lombok.Data; 
    import javax.persistence.*;
    import java.util.Set;
     
    /**
     * @author lidai
     * @date 2018/10/29 14:15
     */
    @Entity
    @Table(name = "t_role")
    @Data
    @EqualsAndHashCode(exclude = {"userSet"})
    public class Role {
     
        @Id
        @GeneratedValue
        private String roleId; 
        private String roleName; 
        private String remark;
     
        @JsonIgnore
        @ManyToMany(fetch = FetchType.LAZY,mappedBy = "roleSet")
        private Set<User> userSet; 
    }

    很多初學者可能對@ManyToMany這個註解存在一些疑惑,下面給出我的理解僅供參考

    @ManyToMany代表多對多的關聯關係

    cascade 屬性

    • CascadeType.ALL:級聯包含所有持久化方法
    • CascadeType.PERSIST只有A類新增時,會級聯B物件新增。若B物件在存(跟新)在則拋異常(讓B變為持久態)
    • CascadeType.MERGE指A類新增或者變化,會級聯B物件(新增或者變化)
    • CascadeType.REMOVE只有A類刪除時,會級聯刪除B類;

    @JoinTable關聯中間表,如User與Role的中間表為t_userhttp://www.cppcns.com_role

    • name:中間表名
    • JoinColumns:中間表與第一張表關聯的外來鍵(第一張表在user中即為user表)
    • inverseJoinColumns:與JoinColumns類似,為第二張表關聯的外來鍵

    fetch

    • FetchType.EAGER:立即載入
    • FetchType.LAZY:懶載入

    mappedBy = "roleSet":roleSet幾位User表中的List<Role>屬性名

    以上為第一種解決方法

    二、將雙向關聯改為單向關聯

    刪除Role表中的如下程式碼即可

        @JsonIgnore
        @ManyToMany(fetch = RtFqfpZTBFetchType.LAZY,mappedBy = "roleSet")
        private Set<User> userSet;

    只不過單向關聯時不能通過Role查詢到User的資訊

    單向多對多@ManyToMany的使用和理解

    • 單向多對多:就是一個實體類可以獲取到另外一個實體類
    • 多對多:一個員工可以擁有多個角色,一個角色可以對應多個員工
        //角色單向多對多:配置中間表
        //多對多:一個員工可以擁有多個角色,一個角色可以對應多個員工
        @ManyToMany(fetch = FetchType.LAZY)//配置懶載入
        //JoinTable是中間表表名,joinColumns指定中間表中關聯自己ID的欄位,  joinColumn是列名,inverseJoinColumns表示中間表中關聯對方ID的欄位。
        @JoinTable(name = "employee_role",joinColumns = @JoinColumn(name = "employee_id"),inverseJoinColumns = @JoinColumn(name = "role_id"))
        @JsonIgnore //生成json是忽略這個屬性(資料大多,全部拿到沒有意義,還有可能造成死迴圈)
        //將角色設定進來 有多個角色不能重複
        private Set<Role> roles = new HashSet<>();
    

    以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。