2013-01-07 39 views
1

我實際上是用不同的過濾器創建研究。JpaSpecificationExecutor:具有規格的複雜查詢

當我使用JpaRepository進行簡單查詢時,我發現JpaSpecificationExecutor使用Criterias進行動態查詢。

我的問題是我需要創建一個複雜的查詢與一組和count()。 這對羣組來說沒問題,但是我不知道如何覆蓋「選擇」部分來放置「count」指令。

有人可以幫我嗎?

我使用彈簧3.1.2和彈簧JPA數據1.0.3 這裏是我的代碼:

return new Specification<Article>() { 

    @Override 
    public Predicate toPredicate(final Root<Article> root, 
     final CriteriaQuery<?> query, final CriteriaBuilder builder) { 
     //count ??? 
     query.groupBy(root.get(Article_.id)); 
     Predicate p = builder.and(builder.like(root.<String> get(Article_.title), "%" + title + "%")); 

     return p; 
    } 
} 

謝謝!

回答

3

不幸的是不能用彈簧數據規範做到這一點。

你可以看到爲什麼同時仍然使用彈簧的數據在這裏要怎麼辦呢(這裏有一個簡單的查詢只返回一個字段): spring-data specifications - return list of ids instead of objects

要獲得字段列表,你可以使用JPA Tuple。您可以在這裏找到一個例子: JPA & Criteria API - Select only specific columns

短版:您需要創建將使用CriteriaQuery<Tuple>自定義彈簧數據存儲庫。

+1

感謝您的幫助。我選擇了兩個請求。一個用規範獲得我所有的ID。第二個(計數)與一個簡單的查詢匹配我的ID。 – user1838850

1

如果你看看Spring Data的org.springframework.data.jpa.repository.support.SimpleJpaRepository,有一種方法叫getCountQuery(..)。這個查詢看起來如下所示;

/** 
* Creates a new count query for the given {@link Specification}. 
* 
* @param spec can be {@literal null}. 
* @return 
*/ 
private TypedQuery<Long> getCountQuery(Specification<T> spec) { 

    CriteriaBuilder builder = em.getCriteriaBuilder(); 
    CriteriaQuery<Long> query = builder.createQuery(Long.class); 

    Root<T> root = applySpecificationToCriteria(spec, query); 
    query.select(builder.count(root)); 

    return em.createQuery(query); 
} 

此使用在Spring數據JPA的可分頁組件,並且可以提供一種解決方案

+1

你好,謝謝你的回答,但是這種方法只是簡單計數。我怎樣才能讓一個querylike「選擇a.value,由a.value從A組中計數(a.id)」? – user1838850

+0

Spring Data JPA,如rchukh所述,可以完成自定義查詢。如果您已經擁有SQL語句,您可以讓實體管理器將其作爲NativeQuery執行,然後將結果映射回自己的對象 –