簡體   English   中英

Spring Data JPA Select Distinct

[英]Spring Data JPA Select Distinct

我有一種情況,我需要select distinct a.address from Person a (其中address是Person內的Address實體)類查詢構建一個select distinct a.address from Person a

我使用Specification來動態構建我的where子句並使用findAll(Specification<T>)函數來獲取結果。 問題是我不能使用規范來構建我的select子句,因此不能使用findAll(Spcification)函數。

做這樣的事情最好的方法是什么?

我遇到了同樣的問題,所以萬一這會幫助別人,這就是我所做的:

規范正在轉換為where子句,而findAll(Specification<T>)函數正在創建自己的select子句。 所以我們無法通過某種方式使用findAll(Specification<T>)函數來解決這個問題。 我已經有了自定義存儲庫,它擴展了SimpleJpaRepository ,所以我添加了一個新方法:

@Override
    @Transactional(readOnly = true)
    public List<Object> findDistinctValues(Specifications<T> spec, String columnName) {
        return getQuery(spec, columnName).getResultList();
    }

    protected TypedQuery<Object> getQuery(Specification<T> spec, final String distinctColumnName) {

        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<Object> query = builder.createQuery(Object.class);
        Root<T> root = applySpecificationToCriteria(spec, query);

        if (null != distinctColumnName) {
            query.distinct(true);
            query.multiselect(root.get(distinctColumnName));
        }

        // We order by the distinct column, Asc
        query.orderBy(builder.asc(root.get(distinctColumnName)));

        return em.createQuery(query);
    }

applySpecificationToCriteria位於SimpleJpaRepository類中。

現在您可以使用findDistinctValues方法。

由於這是谷歌的首要問題,我會在這里發布答案。

在規范中,您可以訪問查詢,因此您可以這樣做

query.distinct(true);

完整示例,導致此類SQL發出:

2015-04-27 12:03:39 EEST [7766-759] postgres @ sales LOG:執行:SELECT DISTINCT t1.ID,t1.NAME,t1.WEBNAME,t1.WEBORDER,t1.PVGROUPPARENT_ID,t1.SITE_ID FROM PRODUCTVARIANT t0,PVGROUP t1 WHERE((t0.PRODUCTTYPE_ID = $ 1)AND(t0.PVGROUP_ID = t1.ID))2015-04-27 12:03:39 EEST [7766-760] postgres @ sales DETAIL:參數:$ 1 =' 4608bdc9-d0f2-4230-82fd-b0f776dc2cfd”

public static Specification<PVGroup> byProductType(final ProductType pt) {
        return (final Root<PVGroup> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) -> {

            query.distinct(true);
            final CollectionJoin<PVGroup, ProductVariant> jPV = root.join(PVGroup_.productVariant);

            final Path<ProductType> ptPath = jPV.get(ProductVariant_.productType);

            return builder.equal(ptPath, pt);
        };
    }
}

快速而骯臟的解決方案是使用Set過濾結果:

Set<...> set = new HashSet<...>( findAll( ... ) )

並確保equals()hashCode()在域類上相關實現:-)

干杯,

好! 您可以在JPQL使用distinct ,也可以在特定列中使用distinct 它已經在這里了 參考在JPA中使用DISTINCT

這會有用嗎?

List<Person> findDistinctPeopleByAddress(String lastname, String firstname);

然后通過列表迭代並使用Person.getAddress()?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM