2016-03-02 81 views
3

我遇到一個問題,我需要使用LEAST和GREATEST函數連接兩個表,但使用JPA CriteriaQuery。下面是我試圖複製我已經看過CriteriaBuilder.least(..)greatest(..),但我有困難的時候,試圖瞭解如何創建Expression<T>傳遞給兩個函數的SQL ...帶有LEAST和GREATEST函數的JPA CriteriaQuery

select * from TABLE_A a 
inner join TABLE_X x on 
(
    a.COL_1 = least(x.COL_Y, x.COL_Z) 
    and 
    a.COL_2 = greatest(x.COL_Y, x.COL_Z) 
); 

回答

5

創建了一個示例春數據JPA的應用程序,演示這些JPA例子事實證明,CriteriaBuilder不支持調用最少,GREATEST作爲非集合功能,並可通過使用CriteriaBuilder.function(..)訪問,如下所示:

Predicate greatestPred = cb.equal(pathA.get(TableA_.col2), 
        cb.function("greatest", String.class, 
          pathX.get(TableX_.colY), pathX.get(TableX_.colZ))); 
3

比較兩列並獲取最小/最大值的最簡單方法是使用CASE語句。

在JPQL,查詢看起來像

select a from EntityA a join a.entityXList x 
    where a.numValueA=CASE WHEN x.numValueY <= x.numValueZ THEN x.numValueY ELSE x.numValueZ END 
    and a.numValueB=CASE WHEN x.numValueY >= x.numValueZ THEN x.numValueY ELSE x.numValueZ END 

您可以使用代碼的CriteriaBuilder.selectCase()相當於但是我從來沒有CriteriaBuilder的大風扇。如果需求迫使你使用CriteriaBuilder,那麼請讓我知道,我可以嘗試編碼等效。

CriteriaBuilder最小/最大值旨在獲取一列中所有條目的最小值/最大值。假設你想獲得具有最大字符串名稱的實體。該代碼看起來像

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
CriteriaQuery query = cb.createQuery(EntityX.class); 
Root<EntityX> root = query.from(EntityX.class); 

Subquery<String> maxSubQuery = query.subquery(String.class); 
Root<EntityX> fromEntityX = maxSubQuery.from(EntityX.class); 
maxSubQuery.select(cb.greatest(fromEntityX.get(EntityX_.nameX))); 
query.where(cb.equal(root.get(EntityX_.nameX), maxSubQuery)); 

我在

https://github.com/juttayaya/stackoverflow/tree/master/JpaQueryTest

+0

不幸的是,定義最小/最大通過CriteriaBuilder的謂詞是我的要求。因爲,正如你所指出的那樣,最大也是最不重要的是在單個表達式(例如Column)上運行的聚合函數,所以我們需要將兩列轉換爲單列,可能需要通過樞軸或子查詢操作,如上所述。幸運的是,還有另一種方法可以調用我希望實現的功能... –