繁体   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