@ManyToMany 三个表之间的关系 [英] @ManyToMany Relationship Between Three Tables

查看:31
本文介绍了@ManyToMany 三个表之间的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Spring JPA 应用程序中有三个独立的实体 - 用户、部门、角色

I have three separate entities in my Spring JPA application - User, Department, Role

我的数据库中有一个连接表来关联每个实体:USER_DEPARTMENT_ROLE

I have a single join table in my database to relate each of these Entities: USER_DEPARTMENT_ROLE

我的问题是,如何在实体类中定义这种关系?我是否必须在每个单独的实体中定义 @ManyToMany 关系?我知道如何定义两个表之间的这种关系,但对于两个以上我不知道从哪里开始.

My question is, how can I define this relation in my entity classes? Do I have to define a @ManyToMany relationship in each of the separate entities? I know how to define this relationship between two tables, but for more than two I'm not sure where to start.

感谢任何帮助!

推荐答案

如果您的连接表中映射了两个以上的关系,那么我建议创建一个单独的实体,用于映射该特定表.

If you have more than two relations mapped in your join table then i would suggest creating a separate entity which would be used for mapping that particular table.

问题是您是否可以有一个不同的 id 列作为人工主键,或者您必须坚持从三个外键构建复合主键.

The question is whether you can have a distinct id column which would serve as an artificial primary key or you have to stick with the composite primary key build from the three foreign keys.

如果您可以添加该人工 ID(这是设计数据库的现代方式),那么您的映射应如下所示:

If you can add that artificial id (which is the modern way of designing your database) then your mapping should look something like the following:

选项 1

class User {
    @OneToMany(mappedBy = "user", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<UserDepartmentRoleLink> userDepartmentRoleLinks;
}

class Department{
    @OneToMany(mappedBy = "department", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<UserDepartmentRoleLink> userDepartmentRoleLinks;
}

class Role{
    @OneToMany(mappedBy = "role", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<UserDepartmentRoleLink> userDepartmentRoleLinks;
}

class UserDepartmentRoleLink {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "department_id")
    private Department department;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "role_id")
    private Role role;

}

关于为多对多关系设置级联类型很棘手,对于涉及三个表的多对多甚至更棘手,因为每个实体都可以根据情况扮演父级或子级的角色..我建议只坚持使用cascade = {CascadeType.PERSIST, CascadeType.MERGE} 并手动处理其他操作.

Regarding setting the cascade types for the many to many relatioship is tricky and for many to many involving three tables is even trickier as every entity can play a role of parent or child depending on the circumstances.. i would suggest sticking only with the cascade = {CascadeType.PERSIST, CascadeType.MERGE} and handling other operations manually.

如果您必须使用复合主键,那么您应该添加额外的 Id 类并将链接实体更改为以下内容:

If you have to stay with the composite primary key then you should add additional Id class and change the link entity to the following:

选项 2

class User {
    @OneToMany(mappedBy = "linkPk.user", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<UserDepartmentRoleLink> userDepartmentRoleLinks;
}

class Department{
    @OneToMany(mappedBy = "linkPk.department", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<UserDepartmentRoleLink> userDepartmentRoleLinks;
}

class Role{
    @OneToMany(mappedBy = "linkPk.role", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<UserDepartmentRoleLink> userDepartmentRoleLinks;
}

链接表

class UserDepartmentRoleLink {

    @EmbeddedId
    private UserDepartmentRoleLinkId linkPk 
          = new UserDepartmentRoleLinkId(); 

    @Transient
    public User getUser() {
        return getLinkPk().getUser();
    }

    @Transient
    public User getDepartment() {
        return getLinkPk().getDepartment();
    }

    @Transient
    public User getRole() {
        return getLinkPk().getRole();
    }    
 }

@Embeddable
public class UserDepartmentRoleLinkId implements java.io.Serializable {

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "department_id")
    private Department department;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "role_id")
    private Role role;

最重要的是,您可以在这里使用多对多,如本文所述 -> 示例.但在我看来,如果您按上述方式映射该链接表,您会省去很多麻烦.最后电话是你的..

The bottom line is that you can use Many To Many here like outlined in this post -> example. But in my opinion you would save yourself a lot of headache if you map that link table as above. In the end the call is yours..

这篇关于@ManyToMany 三个表之间的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆