我只了解 DB 和 JPA/Hibernate 的基础知识。我必须管理一个用户表,其中一个用户可以拥有多个角色。这些角色包含在目录表中,在我的用户公式中,我不假装管理/修改该目录表,我只需要目录值作为添加或删除用户的参考。 我认为最好的方法是在用户和角色之间创建一个关系表来保存用户及其角色“User_Roles”(除非有更有效的方法)。
我不允许修改角色实体,因为它在我的应用程序的许多其他独立于用户表的区域中用于不同的目的。
我看过很多例子,但我仍然不知道哪一个完全适合我的具体需求。如何使用 JPA 和 Hibernate 将我的用户及其角色映射到单个实体中?
提前非常感谢您的回答。
在您的情况下,您必须使用@ManyToMany来关联两个表。
那应该看看这个:
@Entity
@Table(name = "User")
public class User {
...
@ManyToMany
@JoinTable(name = "User_Roles", joinColumn = "id_person")
private Set<Role> roles = new HashSet<>;
}
@Entity
@Table(name = "Role")
public class Role {
...
@ManyToMany(mappedBy = "roles")
private Set<User> users = new HashSet<>;
}
您所描述的是一对多关系,但它是在
User
和连接表 - User_Roles
之间。由于您无法避免连接表,因此最好的办法是使用 @ManyToMany
和 @JoinTable
注释来映射关系。请记住使用 Set
而不是 List
。那么您不需要 joinint 表的实体。
您可以在此博文中找到有关此主题的讨论。
根据上面的屏幕,我理解用户可以分配超过 1 个角色。 即 1 个用户可以映射到多个角色,1 个角色可以映射到多个用户。
因此用户和角色之间的关系是多对多的。
可以使用第三个表(称为映射表)来实现多对多关系。
所以,我们在您的示例中有下表:-
用户
用户角色
角色
@Entity
@Table(name = "user")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
@Id
@SequenceGenerator(name = "USER_ID_GENERATOR", sequenceName = "USER_SEQ",
allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_ID_GENERATOR")
@Column(name = "user_id")
private Long userId;
@OneToOne
@JoinColumn(name = "persion_id")
private person person;`
enter code
here`
@Basic
@Column(name = "date")
private Date date;
@Basic
@Column(name = "observations")
private String observations;
@Basic
@Column(name = "text")
private String text;
@JsonIgnore
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<UserRoles> users = new ArrayList<>();
}
@实体 @Table(名称=“角色”) @JsonInclude(JsonInclude.Include.NON_NULL) 公开课角色{
@Id
@SequenceGenerator(name = "ROLE_ID_GENERATOR", sequenceName = "ROLE_SEQ",
allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ROLE_ID_GENERATOR")
@Column(name = "role_id")
private Long roleId;
@Basic
@Column(name = "id1")
private Long idOne;
@Basic
@Column(name = "id1")
private Long idTwo;
@Basic
@Column(name = "id1")
private Long idThree;
@Basic
@Column(name = "text")
private String text;
@JsonIgnore
@OneToMany(mappedBy = "role", cascade = CascadeType.ALL)
private List<UserRoles> users = new ArrayList<>();
}
@实体 @盖特 @塞特 @Table(名称 = "用户角色") @JsonInclude(JsonInclude.Include.NON_NULL) @审计 公共类 UserRoles {
private static final long serialVersionUID = 1L;
@EmbeddedId
UserRolesKey userRoleId;
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("role_id")
@JoinColumn(name = "role_id")
Roles role;
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("user_id")
@JoinColumn(user_id)
User user;
@PrePersist
private void prePersist() {
super.onPrePersist();
if (this.getId() == null) {
UserRolesKey mapKey = new UserRolesKey();
mapKey.setRoleId(this.getRole().getRoleId());
mapKey.setUserRoleId(this.getUser().getUserId());
this.setId(mapKey);
}
}
}
保存时,您只需使用所有 uaerRoles 映射实体填充用户实体并保留它。 jpa将保存所有详细信息。
在更新分配给用户的角色时,您需要获取用户实体并通过添加新的 userRoles 实体并取消要删除的时间来更新映射。
为了简单起见:这种方式更灵活,以防在连接表上添加新属性
@Table(name = "User")
public class User {
@OneToMany(mappedBy = "user")
Set<UserRoles> userRoles;
}
@Table(name = "Role")
public class Role {
@OneToMany(mappedBy = "role")
Set<UserRoles> userRoles;
}
@Table(name = "user_roles")
public class UserRoles {
@ManyToOne
@JoinColumn(name = "user_id")
User user;
@ManyToOne
@JoinColumn(name = "role_id")
Role role;
}
OBS:记得使用HashSet