2011-08-25 55 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