将PosgreSQL转换为Criteria API

问题描述

在我的春季应用中,我有两个桌子。在工人中,有老板,而且两个角色都可以制造物品。 我想知道多少个项目是由确定的上司工作人员制造的(包括上司项目),并且是在11.9.10之后制造的(例如,它的方法应该可变)。 所以方法应该是

public Long fingCountByDateAndWorker(Worker worker,Instant date) 这里的老板工人和肌酐项目的日期

我通过Postgresql中的脚本获得了正确的值,但是我无法通过Criteria API(Java)做出正确的代码 这是脚本:

select distinct COUNT(item.id) FROM worker w1
JOIN worker w2 ON w1.id = w2.boss_id
JOIN item it ON it.date_create >= '2020-01-10 15:51:33'
and (it.worker_id = w2.id or it.worker_id = 2(boss worker id))
where w1.id = 2(boss worker id)

如何将其转换为Java标准API代码

enter image description here

解决方法

您必须指定父实体的ID。请尝试以下方法

public Long findCountByDateAndWorker_WorkerId(Instant date,Long workerId)
,

使用给定的表,您的实体将是这样的:

@Entity
public class Worker{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    Worker boss;

    ...

}


@Entity
public class Item{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne
    Worker worker;

    LocalDate dateCreate;

    ...

}

然后您可以在“方法”中尝试类似的操作:

public Long findCountByDateAndWorker(Worker worker,LocalDate date){
    Long result = 0l;

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Long> cq = cb.createQuery(Long.class);
    Root<Item> r = cq.from(Item.class);
    cq.select(cb.count(r)).where(cb.and(
                        cb.or(cb.equal(r.get(Item_.worker),worker),cb.equal(r.get(Item_.worker).get(Worker_.boss),worker)),cb.greaterThanOrEqualTo(r.get(Item_.dateCreate,date))));
    
    TypedQuery<Long> query = em.createQuery(cq);
    
    try{
        result = query.getSingleResult();
    }catch(NoResultException nre) {}
    
    return result;
}