2

我有两个实体,Ablum 和 Image,它们之间存在多对多关系。我想做一个标准查询来获取所有专辑以及他们拥有多少张图片的计数。我不想先获取所有专辑然后循环结果以获取计数,因为会有很多 sql 请求。我已经工作了两个晚上,完全迷路了。如果找不到出路,也许我需要回退使用 SQL。

4

2 回答 2

3

感谢digitaljoel的启发,我发现CriteriaBuilder有个方法叫“size”,可以放在集合上。下面是代码:

    CriteriaBuilder cb = getCriteriaBuilder();
    CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
    Root<AlbumEntity> albums = query.from(AlbumEntity.class);
    query.select(cb.array(albums.get(AlbumEntity_.id), cb.size(albums.get(AlbumEntity_.images))));
    query.groupBy(albums.get(AlbumEntity_.id));

这里 groupBy 调用是必须的,否则会发生错误。但是这个方法是加载 AlbumEntity 的 ID,而不是实体本身。如果使用以下代码,则可以加载专辑实体:

    query.select(cb.array(albums, cb.size(albums.get(AlbumEntity_.images))));
    query.groupBy(albums.get(AlbumEntity_.id), ...);

groupBy 必须包含专辑实体的所有属性。如果专辑实体具有 blob 类型属性,它仍然不起作用。

于 2011-08-26T13:30:48.020 回答
2

由于您尚未发布 JPA 映射,因此我将不得不做出一些假设,因此我假设每张专辑都有一个List<YourImageClass> images多对多映射。有了这个,这样的事情就可以了。

select a, size(a.images) from Album a

这将返回一个List<Object[]>whereList.get(i)[0]将是专辑,并且List.get(i)[1]将是图像集的相应大小。

或者,您可以定义一个简单的 bean 来选择。就像是

public class AlbumResult {
    private Album album;
    private Integer imageCount;
    public AlbumResult( Album a, Integer size ) {
        album = a;
        imageCount = size;
    }
    // getters and setters here
}

然后你可以做

select new AlbumResult(a, size(a.images)) from Album a;

我从不处理条件查询,但 JPQL 很简单,将其转换为条件查询应该很简单。

于 2011-08-25T15:47:07.073 回答