簡體   English   中英

JPA/Hibernate 在單個查詢中選擇所有帶有子項計數的父字段

[英]JPA/Hibernate SELECT all parent fields with Child count in Single Query

我正在使用 JPA 2.0 和 Hibernate 1.0.1.Final。

我想要在單個查詢中沒有子項的所有父表字段。

換句話說,我想從 SQL 轉換為 JPA/Hibernate 的 CriteriaAPI。

select kgroup.*, count(userGroup.uid) 
from kernelGroup kgroup 
 left join kernelUserGroup userGroup on (kgroup.groupId = userGroup.groupId) 
group by kgroup.groupId

我有以下 JPA 實體。

@Entity
@Table(name="kernel_group")
public class KernelGroup implements Serializable {

  @Id
  private int groupId;

  private boolean autoGroup;

  private String groupName;

  @OneToMany
  private Set<KernelUserGroup> kernelUserGroups;

  private long jpaVersion; 
}


@Entity
@Table(name="kernel_usergroup")
public class KernelUserGroup implements Serializable {

  @EmbeddedId
  private KernelUserGroupPK id;

  private long jpaVersion;

  @ManyToOne
  private KernelGroup kernelGroup;

  @ManyToOne
  private KernelUser kernelUser;
}

@Embeddable
public class KernelUserGroupPK implements Serializable {
  private String uid;
  private int groupId;
}

我當前的標准查詢是這樣的:

CriteriaBuilder cb = em.getCriteriaBuilder();  
CriteriaQuery<KernelGroupDto> cQuery = cb.createQuery(KernelGroupDto.class);  
Root<KernelGroup> root = cQuery.from(KernelGroup.class);  

Join<KernelGroup, KernelUserGroup> userGroupsJoin = root.join(KernelGroup_.kernelUserGroups, JoinType.LEFT);    

cQuery.select(cb.construct(KernelGroupDto.class, root, cb.count(userGroupsJoin.get(KernelUserGroup_.id).get(KernelUserGroupPK_.uid))));

cQuery.groupBy(root.get(KernelGroup_.groupId));    

em.createQuery(cQuery).getResultList();    

現在的問題是,它向數據庫發出多個查詢。 1) 一個查詢來檢索 groupId 和用戶數 2) N 個查詢來檢索每個組的組信息。

我只想要一個查詢來檢索 GroupInfo 並且沒有用戶計數,如上面的 SQL 查詢所示。

請給我好的建議。

使用下面的代碼實現。

CriteriaBuilder cb = em.getCriteriaBuilder();  
CriteriaQuery<KernelGroupDto> cQuery = cb.createQuery(KernelGroupDto.class);  
Root<KernelGroup> root = cQuery.from(KernelGroup.class);  

Join<KernelGroup, KernelUserGroup> userGroupsJoin = 
root.join(KernelGroup_.kernelUserGroups, JoinType.LEFT);    

cQuery.select(cb.construct(KernelGroupDto.class, root. 
<Long>get("id"),cb.count(userGroupsJoin)));
cQuery .groupBy( root.<Long>get("id") );

cQuery.groupBy(root.get(KernelGroup_.groupId));    

em.createQuery(cQuery).getResultList(); 

此代碼將起作用。 為孩子計數。

你必須有類 KernelGroupDto(Long id, Long childCount) 的構造函數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM