具有LEAST和GREATESTfunction的JPA CriteriaQuery

我有一个问题,我需要使用LEAST和GREATEST函数连接两个表,但使用JPA CriteriaQuery。 这是我想要复制的SQL …

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) ); 

我看过CriteriaBuilder.least(..)和最大的(..) ,但是我很难理解如何创建Expression以传递给任一函数。

事实certificate,CriteriaBuilder确实支持将LEAST和GREATEST作为非聚合函数调用,并且可以使用CriteriaBuilder.function(..)进行访问,如下所示:

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

比较两列并获得最小/最大值的最简单方法是使用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最小/最大是用于获取一列中所有条目的最小/最大值。 假设您希望获得具有字母顺序最大的String名称的Entity。 代码看起来像

 CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery query = cb.createQuery(EntityX.class); Root root = query.from(EntityX.class); Subquery maxSubQuery = query.subquery(String.class); Root fromEntityX = maxSubQuery.from(EntityX.class); maxSubQuery.select(cb.greatest(fromEntityX.get(EntityX_.nameX))); query.where(cb.equal(root.get(EntityX_.nameX), maxSubQuery)); 

我创建了一个示例Spring Data JPA应用程序,用于演示这些JPA示例

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