Hibernate 将用户关系映射到实体
Hibernate mapping user relation to entities
假设我们有 Hibernate 实体 User
,其中包含 username
、password
、roles
等基本字段。
现在我们有一个实体,例如 Car
。
User
与 Car
有 OneToOne
关系,因为他可以拥有汽车。但除此之外,他还与 Car
有 OneToMany
关系,因为他也拥有 children 的汽车。但在前端,我想知道他为自己拥有哪些汽车以及他为 children 拥有哪些汽车。这同样适用于 User
和 motorbike
之间的关系(他自己的,他的 children 等...)
User
实体 class 会是什么样子?将关系映射到“Helper”实体(例如 UserData
:
中是否好?
@Entity
@Data
@Table( name = "users",
uniqueConstraints = {
@UniqueConstraint(columnNames = "username")
})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
@Size(max = 150)
private String username;
@NotBlank
@Size(max = 120)
private String password;
@OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "USER_DATA_ID")
private UserData userData;
UserData
:
@Entity
@Data
@Table( name = "user_data")
public class UserData {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "OWN_CAR_ID")
private Car ownCar;
@OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "PARTNER_CAR_ID")
private Car partnerCar;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable( name = "user_children_cars",
joinColumns = @JoinColumn(name = "user_data_id"),
inverseJoinColumns = @JoinColumn(name = "car_id"))
private Set<Car> childrenCars = new HashSet<>();
public boolean addToChildrenCarSet(Car c) {
return childrenCars.add(c);
}
public UserData() {
}
}
当你征求意见时,我会说如果你使用中间实体 user_data,它会变得不必要的复杂。 :-) 向用户添加更多字段和键并没有真正的缺点 class - 性能可能也比使用 EAGER 抓取更好。如果性能有问题,请稍后再优化查询,然后现在拆分 table。
还有 @ManyToMany
我会避免 - 最好自己创建中间 table 和关系。您可以查看 https://bootify.io 并在那里创建您的数据库模式。没有 EAGER 获取,也没有 CascadeType.ALL(在特殊情况下都是好主意),您可能会添加更多问题,然后以任何方式提供实际帮助。
所以 addToChildrenCarSet
方法将以 @Service
class 结束,在 @Transactional
的方法中,在我的提议中。
假设我们有 Hibernate 实体 User
,其中包含 username
、password
、roles
等基本字段。
现在我们有一个实体,例如 Car
。
User
与 Car
有 OneToOne
关系,因为他可以拥有汽车。但除此之外,他还与 Car
有 OneToMany
关系,因为他也拥有 children 的汽车。但在前端,我想知道他为自己拥有哪些汽车以及他为 children 拥有哪些汽车。这同样适用于 User
和 motorbike
之间的关系(他自己的,他的 children 等...)
User
实体 class 会是什么样子?将关系映射到“Helper”实体(例如 UserData
:
@Entity
@Data
@Table( name = "users",
uniqueConstraints = {
@UniqueConstraint(columnNames = "username")
})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
@Size(max = 150)
private String username;
@NotBlank
@Size(max = 120)
private String password;
@OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "USER_DATA_ID")
private UserData userData;
UserData
:
@Entity
@Data
@Table( name = "user_data")
public class UserData {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "OWN_CAR_ID")
private Car ownCar;
@OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "PARTNER_CAR_ID")
private Car partnerCar;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable( name = "user_children_cars",
joinColumns = @JoinColumn(name = "user_data_id"),
inverseJoinColumns = @JoinColumn(name = "car_id"))
private Set<Car> childrenCars = new HashSet<>();
public boolean addToChildrenCarSet(Car c) {
return childrenCars.add(c);
}
public UserData() {
}
}
当你征求意见时,我会说如果你使用中间实体 user_data,它会变得不必要的复杂。 :-) 向用户添加更多字段和键并没有真正的缺点 class - 性能可能也比使用 EAGER 抓取更好。如果性能有问题,请稍后再优化查询,然后现在拆分 table。
还有 @ManyToMany
我会避免 - 最好自己创建中间 table 和关系。您可以查看 https://bootify.io 并在那里创建您的数据库模式。没有 EAGER 获取,也没有 CascadeType.ALL(在特殊情况下都是好主意),您可能会添加更多问题,然后以任何方式提供实际帮助。
所以 addToChildrenCarSet
方法将以 @Service
class 结束,在 @Transactional
的方法中,在我的提议中。