如何检索此 Hibernate @ManyToOne 关系中记录的所有 children?
How can I retrieve all the children of a record in this Hibernate @ManyToOne relation?
我正在使用 Spring Data JPA 和 Hibernate 映射开发 Spring 引导项目。我对如何实现以下查询有以下疑问。
我有一个 User 实体 class 是这样的:
@Entity
@Table(name = "portal_user")
@Getter
@Setter
public class User implements Serializable {
private static final long serialVersionUID = 5062673109048808267L;
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name = "first_name")
@NotNull(message = "{NotNull.User.firstName.Validation}")
private String firstName;
@Column(name = "middle_name")
private String middleName;
@Column(name = "surname")
@NotNull(message = "{NotNull.User.surname.Validation}")
private String surname;
@Column(name = "sex")
@NotNull(message = "{NotNull.User.sex.Validation}")
private char sex;
@Column(name = "birthdate")
@NotNull(message = "{NotNull.User.birthdate.Validation}")
private Date birthdate;
@Column(name = "tax_code")
@NotNull(message = "{NotNull.User.taxCode.Validation}")
private String taxCode;
@Column(name = "e_mail")
@NotNull(message = "{NotNull.User.email.Validation}")
private String email;
@Column(name = "pswd")
@NotNull(message = "{NotNull.User.pswd.Validation}")
private String pswd;
@Column(name = "contact_number")
@NotNull(message = "{NotNull.User.contactNumber.Validation}")
private String contactNumber;
@Temporal(TemporalType.DATE)
@Column(name = "created_at")
private Date createdAt;
@Column(name = "is_active")
private boolean is_active;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
@JsonManagedReference
private Set<Address> addressesList = new HashSet<>();
@ManyToMany(cascade = { CascadeType.MERGE })
@JoinTable(
name = "portal_user_user_type",
joinColumns = { @JoinColumn(name = "portal_user_id_fk") },
inverseJoinColumns = { @JoinColumn(name = "user_type_id_fk") }
)
Set<UserType> userTypes;
@ManyToOne(fetch = FetchType.EAGER)
@JsonProperty("subagent")
private User parent;
public User() {
super();
}
public User(String firstName, String middleName, String surname, char sex, Date birthdate, String taxCode,
String email, String pswd, String contactNumber, Date createdAt, boolean is_active) {
super();
this.firstName = firstName;
this.middleName = middleName;
this.surname = surname;
this.sex = sex;
this.birthdate = birthdate;
this.taxCode = taxCode;
this.email = email;
this.pswd = pswd;
this.contactNumber = contactNumber;
this.createdAt = createdAt;
this.is_active = is_active;
}
}
这个 class 的实例代表我系统的用户。一个用户可以有一个特定的parent(这个概念类似于推荐的概念:一个用户可以在系统中带来另一个用户)。这是由 ManyToOne 递归关系处理的:
@ManyToOne(fetch = FetchType.EAGER)
@JsonProperty("subagent")
private User parent;
基本上一个用户包含的是parent(将him\her带入平台)。它工作正常。因此检索用户我可以很容易地检索谁是它的 parent 的信息(它包含在检索到的用户 object 中)。
现在我需要实现相反的行为:我必须定义一个从 parent 开始检索其所有 children.
的“查询”
之前的用户实体class映射以下数据库table:
荧光笔parent_id包含定义这个递归关系的FK。所以它包含另一个用户的 PK,即 parent.
我有这个 UserRepository 存储库接口(它扩展了 JpaRepository 接口)
public interface UsersRepository extends JpaRepository<User, Integer> {
User findByemail(String email);
List<User> findByUserTypes_TypeName(String typeName);
}
如您所见,我使用的是“按方法查询”样式。是否有可能使用“按方法查询”样式实现这样的行为? (如果 JPQL 也可以)
你可以做到
List<User> findByParent_Id(Integer id);
或者你可以这样做
@Query("SELECT u FROM User u WHERE u.id = ?1")
List<User> getReferredUsers(Integer id);
用户与 parent 之间的关系在给定代码中是单向的。通过使其成为双向的,可以很容易地以任何一种方式查询数据。
参考下面的代码使其成为双向的。还要确保相关的 FetchType 以避免性能风险。这里 FetchType.LAZY 用于一对多关联,因此它在需要时使用代理引用查询数据。
@ManyToOne(fetch = FetchType.EAGER)
@JsonProperty("subagent")
@JsonBackReference
private User parent;
@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent")
private Set<User> userSet = new HashSet<>();
Child 实体仅在使用 parent.getUserSet 时获取,因为 FetchType.Lazy
public Set<User> getUsers(int id) {
User parent = userRepository.getById(id);
return parent.getUserSet();
}
我正在使用 Spring Data JPA 和 Hibernate 映射开发 Spring 引导项目。我对如何实现以下查询有以下疑问。
我有一个 User 实体 class 是这样的:
@Entity
@Table(name = "portal_user")
@Getter
@Setter
public class User implements Serializable {
private static final long serialVersionUID = 5062673109048808267L;
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name = "first_name")
@NotNull(message = "{NotNull.User.firstName.Validation}")
private String firstName;
@Column(name = "middle_name")
private String middleName;
@Column(name = "surname")
@NotNull(message = "{NotNull.User.surname.Validation}")
private String surname;
@Column(name = "sex")
@NotNull(message = "{NotNull.User.sex.Validation}")
private char sex;
@Column(name = "birthdate")
@NotNull(message = "{NotNull.User.birthdate.Validation}")
private Date birthdate;
@Column(name = "tax_code")
@NotNull(message = "{NotNull.User.taxCode.Validation}")
private String taxCode;
@Column(name = "e_mail")
@NotNull(message = "{NotNull.User.email.Validation}")
private String email;
@Column(name = "pswd")
@NotNull(message = "{NotNull.User.pswd.Validation}")
private String pswd;
@Column(name = "contact_number")
@NotNull(message = "{NotNull.User.contactNumber.Validation}")
private String contactNumber;
@Temporal(TemporalType.DATE)
@Column(name = "created_at")
private Date createdAt;
@Column(name = "is_active")
private boolean is_active;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
@JsonManagedReference
private Set<Address> addressesList = new HashSet<>();
@ManyToMany(cascade = { CascadeType.MERGE })
@JoinTable(
name = "portal_user_user_type",
joinColumns = { @JoinColumn(name = "portal_user_id_fk") },
inverseJoinColumns = { @JoinColumn(name = "user_type_id_fk") }
)
Set<UserType> userTypes;
@ManyToOne(fetch = FetchType.EAGER)
@JsonProperty("subagent")
private User parent;
public User() {
super();
}
public User(String firstName, String middleName, String surname, char sex, Date birthdate, String taxCode,
String email, String pswd, String contactNumber, Date createdAt, boolean is_active) {
super();
this.firstName = firstName;
this.middleName = middleName;
this.surname = surname;
this.sex = sex;
this.birthdate = birthdate;
this.taxCode = taxCode;
this.email = email;
this.pswd = pswd;
this.contactNumber = contactNumber;
this.createdAt = createdAt;
this.is_active = is_active;
}
}
这个 class 的实例代表我系统的用户。一个用户可以有一个特定的parent(这个概念类似于推荐的概念:一个用户可以在系统中带来另一个用户)。这是由 ManyToOne 递归关系处理的:
@ManyToOne(fetch = FetchType.EAGER)
@JsonProperty("subagent")
private User parent;
基本上一个用户包含的是parent(将him\her带入平台)。它工作正常。因此检索用户我可以很容易地检索谁是它的 parent 的信息(它包含在检索到的用户 object 中)。
现在我需要实现相反的行为:我必须定义一个从 parent 开始检索其所有 children.
的“查询”之前的用户实体class映射以下数据库table:
荧光笔parent_id包含定义这个递归关系的FK。所以它包含另一个用户的 PK,即 parent.
我有这个 UserRepository 存储库接口(它扩展了 JpaRepository 接口)
public interface UsersRepository extends JpaRepository<User, Integer> {
User findByemail(String email);
List<User> findByUserTypes_TypeName(String typeName);
}
如您所见,我使用的是“按方法查询”样式。是否有可能使用“按方法查询”样式实现这样的行为? (如果 JPQL 也可以)
你可以做到
List<User> findByParent_Id(Integer id);
或者你可以这样做
@Query("SELECT u FROM User u WHERE u.id = ?1")
List<User> getReferredUsers(Integer id);
用户与 parent 之间的关系在给定代码中是单向的。通过使其成为双向的,可以很容易地以任何一种方式查询数据。
参考下面的代码使其成为双向的。还要确保相关的 FetchType 以避免性能风险。这里 FetchType.LAZY 用于一对多关联,因此它在需要时使用代理引用查询数据。
@ManyToOne(fetch = FetchType.EAGER)
@JsonProperty("subagent")
@JsonBackReference
private User parent;
@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent")
private Set<User> userSet = new HashSet<>();
Child 实体仅在使用 parent.getUserSet 时获取,因为 FetchType.Lazy
public Set<User> getUsers(int id) {
User parent = userRepository.getById(id);
return parent.getUserSet();
}