我如何实现 JPQL 查询来检索所有具有特定类型的用户(使用多对多关系实现)?

How can I implement a JPQL query retrieving all the user having a specific type (implemented using a MANY TO MANY relation)?

我正在开发一个 Spring 引导项目,但我不太喜欢 Hibernate/JPA,我对如何使用它执行以下查询有以下疑问。

我有这 2 个实体 classes:

用户:它包含代表我门户上用户的记录:

@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 int 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;
    
    //private String test;
    
    @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;
    
    @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;
    

    public User() {
        super();
        // TODO Auto-generated constructor stub
    }


    public User(String firstName, String middleName, String surname, char sex, Date birthdate, String taxCode,
            String email, String pswd, String contactNumber, Date createdAt) {
        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;
    }

}

每个用户都可以与一个或多个角色相关联,此 多对多 关系:

@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;

如您所见,此字段与名为 portal_user_user_type 的数据库 table 相关联,它仅包含用户的 PK table user_type table 的 PK 由以下实体 class:

表示
@Entity
@Table(name = "user_type")
@Getter
@Setter
public class UserType implements Serializable {
    
    private static final long serialVersionUID = 6904959949570501298L;

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    
    @Column(name = "type_name")
    private String typeName;
    
    @Column(name = "description")
    private String description;
    
    //@OneToMany(mappedBy = "userType")
    //@JsonManagedReference
    //private Set<User_UserType> userToUserTypeAssociation = new HashSet<>();
    
    @ManyToMany(cascade = { CascadeType.MERGE })
    @JoinTable(
        name = "user_type_operation", 
        joinColumns = { @JoinColumn(name = "fk_user_type_id") }, 
        inverseJoinColumns = { @JoinColumn(name = "fk_operation_id") }
    )
    Set<Operation> operations;
    

    public UserType() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    public UserType(String typeName, String description) {
        super();
        this.typeName = typeName;
        this.description = description;
    }

}

现在,之前的 class 正在映射 user_type 数据库类型 table,它只能包含一组特定的值。例如,类型名称如 ADMINAGENTCLIENT.

进入我的 Spring 引导项目我有这个存储库接口实现 JpaRepository 接口:

public interface UsersRepository extends JpaRepository<User, Integer> {
    
    User findByemail(String email);

}

目前它只包含一个使用“按方法名称查询”技术实现的查询。

现在我必须根据之前的实体实现另一个更复杂的查询 classes:

我必须检索所有具有特定 UserType.typeName 值的 User 实例。

例如:检索所有 User 记录 UserType.typeName 等于 ADMIN.

是否可以使用按方法名称样式查询来实现它,还是使用 JPQL 更好。如果我怎样才能创建这样的查询? (在 JPQL 中也可以)

您可以使用@Query 批注来编写查询,或者您可以使用 findByUserTypes_TypeNameIn(List typeNameList) 来获取用户类型名称列表,或者使用 findByUserTypes_TypeName(String typeName) 来获取特定的用户类型名称输入名称。