构建CriteriaBuilder查询以比较列表

问题描述 投票:0回答:1

如何比较数据库表中的列表和程序代码中的列表?该数据库具有具有技能的用户个人资料。

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

java sql jpa criteria criteria-api
1个回答
0
投票

我找到了一个解决方案,尽管我认为可以采取不同的方法。

    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();
© www.soinside.com 2019 - 2024. All rights reserved.