在QueryDsl中编写条件查询

问题描述 投票:0回答:2

我有一个名为date的字段的实体和一个名为creationDate的字段。第一个可以为null,后者不是。

而现在我想从某个时间段获得所有物品。如果date不为null,则使用date。如果它为null,那么我们应该使用creationDate作为检查的备份。

为了达到这个目的,我正在尝试组装一个com.querydsl.core.types.Predicate,然后我可以将其传递给我的datare存储库findAll方法。 (我正在使用Spring数据存储库)。

到目前为止我所拥有的:

    QItem item = QItem.item$;
    BooleanExpression predicate = new CaseBuilder()
            .when(item.date.isNotNull())
            .then((Predicate) item.date.between(startDate, endDate))
            .otherwise(item.creationDate.between(startDate, endDate));

在使用我的代码安静时,我收到了这个异常:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: case near line 3, column 7 [select item$
from com.example.entities.Item item$
where case when (item$.date is not null) then (item$.date between ?1 and ?2) else (item$.creationDate between ?1 and ?2) end]; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: case near line 3, column 7 [select item$
from com.example.entities.Item item$
where case when (item$.date is not null) then (item$.date between ?1 and ?2) else (item$.creationDate between ?1 and ?2) end]] with root cause

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: case near line 3, column 7 [select item$
from com.example.entities.Item item$
where case when (item$.date is not null) then (item$.date between ?1 and ?2) else (item$.creationDate between ?1 and ?2) end]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]

这里出了什么问题?

即使出于正确的目的,我还在使用CaseBuilder吗?

问候

querydsl
2个回答
0
投票

好吧,我用类似的东西替换了基于案例的谓词

Predicate withDate = new BooleanBuilder(item.date.isNotNull())
        .and(item.date.between(startDate, endDate));
Predicate withoutDate = new BooleanBuilder(item.date.isNull())
        .and(item.creationDate.between(startDate, endDate));

Predicate combined = new BooleanBuilder(withDate)
        .or(withoutDate);

它的工作原理。我仍然对我的第一种方法出了什么问题感兴趣。


0
投票

即使出于正确的目的,我还在使用CaseBuilder吗?

CaseBuilder用于创建case声明,E.G。

SELECT CASE WHEN some_column = 'A' THEN 'It is A'
            WHEN some_column = 'B' THEN 'It is B'
            ELSE 'It is a different value' END AS some_alias
FROM some_table;

在case语句中的每个条件处,指定返回值。在您的示例中,您希望有条件地选择布尔逻辑。这不是案例陈述的用途。

© www.soinside.com 2019 - 2024. All rights reserved.