如何比较数据库表中的列表和程序代码中的列表?该数据库具有具有技能的用户个人资料。
@ManyToMany(cascade = {CascadeType.MERGE}, fetch = FetchType.EAGER)
@JoinTable(name = "profile_skills",
joinColumns = @JoinColumn(name = "profile_id", referencedColumnName="id"),
inverseJoinColumns = @JoinColumn(name = "skill_id", referencedColumnName="id"))
private Map<Integer, Skill> skills = new TreeMap<>();
需要找到具有适当技能的用户个人资料。我提出了要求,但他选择的个人资料至少与列表中的任何一项匹配。但是,我只需要选择那些具有列表中指示的所有技能(与列表中的所有元素都匹配)的技能即可。
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Profile> cq = cb.createQuery(Profile.class);
Root<Profile> root = cq.from(Profile.class);
MapJoin<Profile, Integer, Skill> skillMapJoin = root.join(Profile_.skills);
Expression<String> nameSkill = skillMapJoin.get(Skill_.name);
List<String> skills = Arrays.asList("Java", "JavaScript");
cq.where(nameSkill.in(skills)).groupBy(root.get(Profile_.id));
TypedQuery<Profile> q = em.createQuery(cq);
List<Profile> profiles = q.getResultList();
例如:Profile1.Skills:“ Java”,“ Scala”,“ Groovy”,“ JavaScript”Profile2.Skills:“ Java”,“ Scala”,“ Groovy”Profile3.Skills:“ Groovy”,“ JavaScript”
我的查询返回结果:Profile1,Profile2,Profile3必须有一个结果:Profile1
请告诉我如何实施所需的请求?如何比较数据库表中的列表和程序代码中的列表?不仅可以使用CriteriaBuilder,还可以使用其他查询选项,例如sql或jpql。
我找到了一个解决方案,尽管我认为可以采取不同的方法。
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Profile> cq = cb.createQuery(Profile.class);
Root<Profile> root = cq.from(Profile.class);
MapJoin<Profile, Integer, Skill> skillMapJoin = root.join(Profile_.skills);
Expression<String> nameSkill = skillMapJoin.get(Skill_.name);
List<String> skills = Arrays.asList("Java", "JavaScript");
Integer sizeListValue = skills.size();
Expression<Long> countSkills = cb.count(exp);
cq.where(nameSkill.in(skills))
.groupBy(root.get(Profile_.id))
.having(cb.equal(countSkills, sizeListValue));
TypedQuery<Profile> q = em.createQuery(cq);
List<Profile> profiles = q.getResultList();