【问题标题】:Building a CriteriaBuilder query to compare lists构建 CriteriaBuilder 查询以比较列表
【发布时间】:2020-01-06 08:31:21
【问题描述】:

如何比较数据库表中的列表和程序代码中的列表?
该数据库具有具有技能的用户配置文件。

    @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】:

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

        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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-11
      • 2012-08-19
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多