【问题标题】:How to check in JPA if joined column contains data with condition如果连接列包含有条件的数据,如何检查 JPA
【发布时间】:2016-08-22 16:34:32
【问题描述】:

我有两张桌子。

个人和他的假期计划。对于这个问题,我们需要知道的一切是 Person 包含 Id 并且 vp 包含此 id 作为外键,以及年份和开始日期结束日期。 Person 可以包含更多的 vp。 因此

    Person          VacPlan
    _______        ____________
   |id     |----->|pers_id     |
                  |year        |
                  |start date  |
                  |end date    |

我需要选择在指定年份在 vp 中没有单一记录的每个人。

类似:select from person where (joined vp where vp.year = :year) is not empty

你有什么想法如何在 JPA 中制作这个(eclipse 链接)

编辑: 这就是标准的样子

List<Predicate> predicates = new ArrayList<>();
List<Predicate> subPredicates = new ArrayList<>();
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<PersonVP> q = cb.createQuery(PersonVP.class);
Root<PersonVP> person = q.from(PersonVP.class);

Subquery<VacationPlanning> subquery = q.subquery(VacationPlanning.class);
Root<VacationPlanning> subRoot = subquery.from(VacationPlanning.class);

Expression<String> exp = person.get("personnelNumber");
subPredicates.add(cb.equal(subRoot.get("year"), year));
subPredicates.add(cb.equal(exp, subRoot.get("perNr")));
subquery.where(cb.and(subPredicates.toArray(new Predicate[subPredicates.size()])));

if (STATUS.FILLED.equals(searchFillStatus)) {
    predicates.add(cb.and(cb.exists(subquery)));
} else if (STATUS.NOT_FILLED.equals(searchFillStatus)) {
    predicates.add(cb.and(cb.not(cb.exists(subquery))));
}

q.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));

q.select(person);
TypedQuery<PersonVP> query = getEntityManager().createQuery(q);

return query.setFirstResult(from)
        .setMaxResults(to)
        .getResultList();

【问题讨论】:

    标签: java mysql oracle jpa


    【解决方案1】:

    您可以使用 NamedQuery 来完成这项工作。 您在您的 Person Entity 文件中使用 @JB Nizet 查询声明一个 NamedQuery

    @NamedQuery(name="VpForYear", query="select p from Person p where not exists(
        select vp.id from Person p2 
        join p2.vacPlans vp
        where p2.id = p.id
        and vp.year = :year)")
    

    你可以像这样使用NamedQuery

    Query query = em.createNamedQuery("VpForYear");
    query.setParameter("year", 2016);
    

    【讨论】:

      【解决方案2】:

      试试这个:

      SELECT p.id 
      FROM person p 
      WHERE p.id NOT IN (SELECT DISTINCT(vp.pers_id)
                    FROM VacPlan vp)
      

      【讨论】:

        【解决方案3】:

        这样的事情应该可以工作:

        select p from Person p where not exists(
            select vp.id from Person p2 
            join p2.vacPlans vp
            where p2.id = p.id
            and vp.year = :year)
        

        【讨论】:

        • 最后我不需要加入。 select p from Person p where not exists (select 1 from VacPla vp where vp.year = 2016 and vp.persId=p.id); 有问题的标准版本。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-30
        • 1970-01-01
        • 2019-06-29
        • 1970-01-01
        相关资源
        最近更新 更多