JPA Criteria Builder를 사용하여 추가 카운트 열이있는 쿼리를 작성하는 방법
Aug 18 2020
데이터베이스에있는 모든 P 개체를 반환하는 JPA 쿼리를 작성하는 데 어려움을 겪고 있으며 그 옆에 propertyA = 1 인 S 자식의 개수를 갖고 싶습니다.
SQL 쿼리
p_table p에서 p. *, (s_table s WHERE p.id = s.p_id 및 s.propertyA = 1에서 count (s.id) 선택) 선택
매핑 :
@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);
답변
JLazar0 Aug 19 2020 at 09:57
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(),
);
생성자가 다음과 같이 multiselect 매개 변수를 사용하여 순서와 유형이 일치하는 결과를 얻으려면 Pojo가 필요합니다.
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;