簡體   English   中英

Spring如何存儲有關2個實體之間關系的信息

[英]Spring how to store information about relationship between 2 entities

我有兩個具有這些字段的實體:

代碼實體:

@Entity
@Table(name = "snippets")
@NoArgsConstructor
@Getter
@Setter
public class Code {

    private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

    @Id
    @GeneratedValue
    private Long id;
    private String code;
    private String date;
    private User author;
    private List<User> allowedUsers;

    public Code(CodeDto code) {
        this.code = code.getCode();
        this.date = LocalDateTime.now().format(formatter);
        this.author = code.getAuthor();
    }
}

用戶實體:

@Entity
@Table(name = "users")
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
public class User implements UserDetails {

    @Id
    @GeneratedValue
    private Long id;
    private String username;
    private String password;
    @Enumerated(EnumType.STRING)
    private UserRole userRole;
    @Transient
    private boolean locked;
    private boolean enabled = true;
    private List<Code> codeList;


    public User(String username, String password, UserRole userRole) {
        this.username = username;
        this.password = password;
        this.userRole = userRole;
    }
}

我正在嘗試創建一個類似於 github 的應用程序(但當然非常簡化)。 我希望每個用戶都能夠添加一個代碼片段,然后將其訪問權限授予其他用戶。 我想存儲誰是作者以及誰有權訪問每個代碼片段的信息。 我怎樣才能做到這一點?

  • 每個代碼都可以被用戶列表看到:這可以用 OneToMany 關系表示。
  • 每個用戶都有一個代碼列表:這也用 OneToMany 關系表示。

這些關系可以用這個來表示:

@OneToMany @JoinColumn(name = "code_id", referencedColumnName = "id")
private List<Code> codeList;

另一個也可以這樣做:

@OneToMany @JoinColumn(name = "user_id", referencedColumnName = "id")
private List<User> allowedUsers;

我希望每個用戶都能夠添加代碼片段

我假設您實際上是指多個代碼片段,這會更明智。 要實現這一點,您需要在用戶和代碼之間建立一個 OneToMany 關聯,為此您將使用 @OneToMany。

您還沒有提到您正在使用的持久性提供程序,但至少對於 Hibernate,我建議使用雙向關系以避免在添加代碼時進行額外的更新查詢。

當關系是雙向的時,關系的 @ManyToOne 端,也就是所有者端,負責填充實體插入的外鍵列,更多在這里

public class User implements UserDetails {
    ...
    @OneToMany(mappedBy = "writer")
    private Set<Code> codeList = new HashSet<>();

    public void addCode(Code code) {
        codeList.add(code);
        code.setWriter(this);
    }

    public void removeCode(Code code) {
        codeList.remove(code);
        code.setWriter(null);
    }

}

正如我們所說,關聯是雙向的,因此在代碼方面,您將擁有:

public class Code {
    ...
    @ManyToOne(fetch = FetchType.LAZY)
    private User writer;
}

PS1:我將列表切換為設置,因為它是推薦的,更多在這里

PS2:處理雙向OneToMany 關系可能很棘手,即在我們的示例中忘記設置writer 端將導致數據庫中的外鍵為空。 避免這種情況的一個好方法是使用輔助方法來添加和刪除子實體。

然后將其訪問權限授予其他用戶

為此,關聯將是@ManyToMany,以便將其映射到數據庫中的連接表:

public class Code {
    ...
    @ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE})
    @JoinTable(name = "code_viewers",
        joinColumns = @JoinColumn(name = "code_id"),
        inverseJoinColumns = @JoinColumn(name = "viewer_id"))
    private Set<User> viewers = new HashSet<>();
}

再一次,您需要設置關系的另一側:

public class User implements UserDetails {
    ...
    @ManyToMany(mappedBy = "viewers")
    private Set<Code> accessibleCodes = new HashSet<>();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM