2011-08-25 39 views
2

我有两个实体,Ablum和Image,它们有许多关系。 我想做一个标准查询,以获得所有相册和计数他们有多少图像。 我不想先获取所有相册,然后循环结果以获取计数,因为会有很多SQL请求。 我已经工作了两个晚上,完成了迷路。如果找不到出路,也许我需要回退使用SQL。复杂的多对多JPA CriteriaQuery

回答

3

感谢digitaljoel的灵感,我发现CriteriaBuilder有一个方法调用“大小”,可以放在集合上。以下是代码:

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类型属性,它仍然不起作用。

2

因为您还没有发布您的JPA映射,所以我将不得不作出一些假设,所以我假设每张专辑都有一个List<YourImageClass> images用于多对多映射。有了这个,这样的事情会起作用。

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

这将返回一个List<Object[]>其中List.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是足够简单,它应该是微不足道的把它翻译成一个条件查询。

+0

谢谢digitaljoel,但我不能在项目中使用JPQL。但是你的想法激励了我。感谢很多:) – hzywind

+0

是的,你提到你需要一个标准查询在你的问题,这就是为什么我的答案我说,JPQL应该足够简单,可以翻译成标准查询,但由于我从未使用标准我想你会比我做得更快。这里是我从http://www.objectdb.com/java/jpa/query/jpql/collection#Criteria_Query_Collection_Expressions_获取大小函数的地方 – digitaljoel