如何使用JPA Criteria Builder编写带有附加计数列的查询

问题描述

我正在努力编写一个JPA查询,该查询将返回数据库中的所有P对象,并且在它们旁边,我希望对具有propertyA = 1的S个子对象进行计数。

SQL查询

选择p。*,(从s_table s中选择count(s.id) 来自p_table p

的p.id = s.p_id和s.propertyA = 1)

映射:

@Entity
@Table(name = "t_table")
public class PTable{
    @Id
    private String id;

    @Version
    private Long version;

    private String subject;
   
    @OneToMany(cascade = CascadeType.ALL,orphanRemoval = true,fetch = FetchType.EAGER)
    @JoinColumn(name = "p_id",referencedColumnName = "id")
    private Set<STable> sSet = new HashSet<>();
}
 
@Entity
@Table(name = "s_table")
public class STable {

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

    @Column(name = "p_id")
    private String pId;
  
    private String propertyA;
}

此外,您是否想指出任何好的教程,以JPA编写复杂的查询。

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<PTable> q = cb.createQuery(PTable.class);
Root<PTable> c = q.from(PTable.class);

解决方法

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<MyPojo> cq = cb.createQuery(MyPojo.class);

Root<PTable> rootPTable = cq.from(PTable.class);
Join<PTable,STable> joinSTable = rootPTable.join(PTable_.sSet);

Subquery<Long> sqCount = cq.subquery(Long.class);
Root<STable> sqRootSTable = sqCount.from(STable.class);
Join<STable,PTable> sqJoinPTable = sqRootSTable.join(STable_.pSet);

sqCount.where(cb.and(
    cb.equal(sqJoinPTable.get(PTable_.id),rootPTable.get(PTable_.id)),cb.equal(sqRootSTable.get(STable_.propertyA),"1")));

sqCount.select(cb.count(sqRootSTable));

cq.multiselect(
    rootPTable.get(PTable_.id),rootPTable.get(PTable_.version),rootPTable.get(PTable_.subject),joinSTable.get(STable_.id),sqCount.getSelection(),);

您将需要Pojo来获得构造函数具有按顺序匹配的结果,并使用multiselect参数键入,如下所示:

public MyPojo(String pId,Long version,String subject,Long sId,Long count){
    [...]
}

您还必须更改您的实体以正确映射关系,并且双向且懒惰以提高性能,如下所示:

PTable

@OneToMany(mappedBy="p",fetch = FetchType.LAZY)
private Set<STable> sSet;

稳定

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="id")
private PTable p;

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...