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

查看:189
本文介绍了@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天全站免登陆