JPA:如何在SELECT Query中使用CASE

时间:2018-04-05 06:06:07

标签: spring jpa select case parameterized-query

在下面的查询中,我想根据最小和最大年龄选择程序,但关键是每个程序没有必要具有最小和最大年龄,所以我想检查查询是否最小或最大年龄存在比检查参数'age',它应该位于最小和最大年龄之间

查询

@Query("Select p from Program p where (CASE WHEN p.minimumAge!=null AND p.maximumAge==null THEN p.minimumAge<=:age ELSE 0),(CASE WHEN p.minimumAge!=null AND p.maximumAge!=null THEN p.minimumAge<=:age AND p.maximumAge>=:age ELSE 0)")
List<Program> programs(@Param("age")int age);

错误

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: = near line 1, column 108 [Select p from com.ivl.MySportsAcademy.model.Program p where (CASE WHEN p.minimumAge!=null AND p.maximumAge==null THEN p.minimumAge<=:age ELSE 0),(CASE WHEN p.minimumAge!=null AND p.maximumAge!=null THEN p.minimumAge<=:age AND p.maximumAge>=:age ELSE 0)]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:288) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1894) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    ... 48 common frames omitted

1 个答案:

答案 0 :(得分:2)

有几个问题:

  • 错误将您指向第108列p.maximumAge==null - SQL中没有==,只有=
  • 你不能像if语句一样使用CASE来动态添加/删除where子句。

但是,您应该能够使用COALESCE提供null的替代方法,所以如果您这样做:

Select p 
  from Program p 
 where COALESCE(p.maximumAge, :age) >= :age
   and COALESCE(p.minimumAge, :age) <= :age

然后,只要程序的最大年龄为NULL,比较就是:age <= :age(总是如此)。最低限度相同。

希望有所帮助