简体   繁体   English

Spring如何存储有关2个实体之间关系的信息

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

I have two entities that have these fields:我有两个具有这些字段的实体:

Code entity:代码实体:

@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();
    }
}

User entity:用户实体:

@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;
    }
}

I am trying to create an application similar to github (but very simplified of course).我正在尝试创建一个类似于 github 的应用程序(但当然非常简化)。 I want each user to be able to add a code snippet, and later grant access to it to other users.我希望每个用户都能够添加一个代码片段,然后将其访问权限授予其他用户。 I want to store the information who is the author and who has access to each code snippet.我想存储谁是作者以及谁有权访问每个代码片段的信息。 How can I achieve that?我怎样才能做到这一点?

  • Each code can be seen by a list of users: That can be represented with a OneToMany relationship.每个代码都可以被用户列表看到:这可以用 OneToMany 关系表示。
  • Each user has a list of codes: That also is represented with a OneToMany relationship.每个用户都有一个代码列表:这也用 OneToMany 关系表示。

These relationships can be represented using this:这些关系可以用这个来表示:

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

The same can be done for the other:另一个也可以这样做:

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

I want each user to be able to add a code snippet我希望每个用户都能够添加代码片段

I'm assuming you actually mean multiple code snippets, which would be more sensible.我假设您实际上是指多个代码片段,这会更明智。 To achieve that you would need a OneToMany association between the User and Code, for which you would use @OneToMany.要实现这一点,您需要在用户和代码之间建立一个 OneToMany 关联,为此您将使用 @OneToMany。

You haven't mentioned the persistence provider you're using, but at least for Hibernate, I would suggest a bi-directional relation to avoid an extra update query when adding a Code.您还没有提到您正在使用的持久性提供程序,但至少对于 Hibernate,我建议使用双向关系以避免在添加代码时进行额外的更新查询。

When the relation is bi-directional, the @ManyToOne side of the relation, aka the owner side, is in charge of filling the foreign key column on the entity's insert, more here .当关系是双向的时,关系的 @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);
    }

}

As we said, the association is bi-directional, so on the Code side, you would have:正如我们所说,关联是双向的,因此在代码方面,您将拥有:

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

PS1: I switched list to set as it's the recommendation, morehere . PS1:我将列表切换为设置,因为它是推荐的,更多在这里

PS2: Dealing with bi-directional OneToMany relations can be tricky, ie forgetting to set the writer side in our example will result in a null foreign key in the database. PS2:处理双向OneToMany 关系可能很棘手,即在我们的示例中忘记设置writer 端将导致数据库中的外键为空。 A nice way to avoid that is to have helper methods to add and remove a child entity.避免这种情况的一个好方法是使用辅助方法来添加和删除子实体。

and later grant access to it to other users然后将其访问权限授予其他用户

For this, the association would be a @ManyToMany, in order to map it to a join table for in the database :为此,关联将是@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<>();
}

Once more, you need to set the other side of the relation:再一次,您需要设置关系的另一侧:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 关于Spring数据中实体之间的映射 - About Mapping between entities in spring-data 使用 Spring 引导,如何在新表上创建 2 个实体之间的关系并为其提供额外的列? - Using Spring Boot, how can I create the relationship between 2 entities on a new table and give it extra columns? 如何使用 Hibernate &amp; Spring Data JPA 正确注释两个实体之间的这种关系? - How can I properly annotate this relationship between two entities using Hibernate & Spring Data JPA? 如何在3个实体之间映射oneToone和OneToMany关系? - How to map oneToone and OneToMany relationship between 3 entities? Spring实体之间的相互关系 - Spring mutual relationship of entities spring boot中两个实体之间的多对多关系 - many-to-many-relationship between two entities in spring boot 不同方案的两个实体之间的关系 - Spring Boot Data JPA - Relationship between two entities of different schemes - Spring Boot Data JPA 如何在Java中存储有关许多人的信息 - How to store information about many people in Java 如何在Spring Data JPA或Hibernate中存储实体 - How to store entities in Spring Data JPA or hibernate 如何使用Spring Boot JPA在这两个类之间建立一对一的关系?另外,如何保存实体? - How can i establish a one to one relationship between this two classes using spring boot jpa?, also, how do i save the entities?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM