如何解决如何使用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;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。