hibernate order by count加入表并返回pojos列表

时间:2014-10-22 18:59:03

标签: java mysql performance hibernate left-join

假设我有一个包含AnotherEntity集的OneEntity

@Entity
public class OneEntity {

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<AnotherEntity> anotherEntities;

}

现在我在OneEntity中有大约30000行,在AnotherEntity中有大约500000行,一些OneEntities有10-100个AnotherEntity,但是其中一些有1000或更多(这很重要)

现在我希望获得前20个具有最大AnotherEntities计数的OneEntities(但没有AnotherEntities数据,设置将为空,就像我使用延迟集合一样)尽可能快。

Hibernate创建了3个表:OneEntity,OneEntity_AnotherEntity,AnotherEntity。

当我在mysql控制台中处理查询时

SELECT *, COUNT(anotherEntityId) as anotherEntityCount from OneEntity left join OneEntity_AnotherEntity on OneEntity.oneEntityId = OneEntity_AnotherEntity.oneEntityId group by OneEntity.oneEntityId order by anotherEntityCount desc limit 0,20;

带我约 0.3秒,因此我有(例如)下一个字段的下一个字段:

  • oneEntityId;
  • oneEntityName;
  • oneEntityDescription;
  • anotherEntityCount;

现在我想使用hibernate执行此操作,我搜索了这样的解决方案:

criteria.createAlias("anotherEntities", "anotherEntity");
criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("oneEnityId")).add(Projections.count("anotherEntity.anotherEntityId"), "anotherEntityCount"));
criteria.addOrder(Order.desc("anotherEntityCount"));

但在这种情况下我获得下一个数组:

[
  [
    427636,
    52268
  ],
  [
    645779,
    47529
  ],
  and so on...
]

这需要我 13 !!! 秒(在mysql控制台中反对0.3秒)

问题 - 我如何查询由AnotherEntity计数排序的OneEntity并获得OneEntities列表(不包含另一组的其他内容)少于13秒?

1 个答案:

答案 0 :(得分:0)

我猜可以使用hql查询,如下所示:

EntityManager em = ....
Query q = em.createQuery("SELECT new HashMap<e,COUNT(e.id)> FROM OneEntity e ... GROUP BY e.id");
q.getResultList();

它将返回Map列表。希望它适合你。