ada*_*ava 1 java spring hibernate jpa spring-data-jpa
我有一个属性作为类型列表的User实体skills。我想User针对技能列表查询表格,如果所有技能都存在于技能列中,那么除非没有,否则只会找到匹配项。
我为此使用了 JPQL,但它使用IN子句一一匹配列表中的每个元素。
用户类
@Entity(name = "App_User")
//table name "user" is not allowed in postgres
public class User {
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
@Column(name = "user_id", updatable = false, nullable = false)
@Setter(AccessLevel.NONE)
private UUID id;
@Column(name = "user_name")
@NotBlank(message = "Name is mandatory")
private String name;
@Column(name = "user_email")
@NotBlank(message = "Email is mandatory")
private String email;
// Current point balance of the user
@Column(name = "points")
private int points;
@ElementCollection(fetch = FetchType.EAGER)
@Column(name = "skills")
@NotEmpty
private List<String> skills = new ArrayList();
}
Run Code Online (Sandbox Code Playgroud)
我使用的 JPA 查询是
SELECT u FROM App_User u JOIN u.skills skill where skill in :skillList
Run Code Online (Sandbox Code Playgroud)
如果我想匹配这样的技能列表,Arrays.asList("skill1","skill2","skill3")那么我只想要结果中拥有所有这些技能的用户,而不是一两个。以上使用的IN子句返回相同的结果。
我已经读到无法比较 JPQL 中的两个列表,那么我如何使用CriteriaBuilder CriteriaQueryAPI实现这一点?
你可以这样做
@Query(value = "SELECT u FROM User u LEFT JOIN u.skills sk WHERE sk IN :skillList"
+ " GROUP BY u HAVING COUNT( sk) = :skillListSize")
List<User> findBySkills(@Param("skillList") List<String> skills,
@Param("skillListSize") long skillListSize);
Run Code Online (Sandbox Code Playgroud)
在这里,按用户分组,然后检查具有所有技能或不使用大小的组。因此,它将获取所有拥有这些技能的用户。
或者用这种方式
@Query(value = "SELECT u FROM User u LEFT JOIN u.skills sk GROUP BY u"
+ " HAVING SUM(CASE WHEN sk IN (:skillList) THEN 1 ELSE 0 END) = :skillListSize")
List<User> findBySkills(@Param("skillList") List<String> skills,
@Param("skillListSize") long skillListSize);
Run Code Online (Sandbox Code Playgroud)
并且,如果您想要为具有完全相同技能的用户提供不超过给定列表的解决方案,请参阅此解决方案。
| 归档时间: |
|
| 查看次数: |
1213 次 |
| 最近记录: |