我有一个User
实体与skills
属性作为类型列表。我想查询的是User
表格对照技能列表,如果所有技能都出现在技能列中,则仅找到匹配项,除非没有。
我为此使用了 JPQL,但它使用以下命令逐一匹配列表中的每个元素IN
clause.
用户等级
@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();
}
我使用过的JPA查询是
SELECT u FROM App_User u JOIN u.skills skill where skill in :skillList
如果我想匹配这样的技能列表Arrays.asList("skill1","skill2","skill3")
那么我只想要结果中那些拥有所有这些技能的用户,而不是一两个。以上使用IN
子句返回相同的结果。
我读过,不可能在 JPQL 中比较两个列表,所以我如何使用来实现这一点CriteriaBuilder
CriteriaQuery
API?
你可以这样做
@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);
在这里,按用户分组,然后检查具有所有技能或不使用大小的组。因此,它将获取具有所赋予的所有技能的所有用户。
或者使用这种方式
@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);
如果您想要为具有完全相同技能但不超过给定列表的用户提供解决方案,请参阅此solution https://stackoverflow.com/a/62664681/4207306.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)