【问题标题】:How can I use an if/else-statement within predicates?如何在谓词中使用 if/else 语句?
【发布时间】:2021-05-15 08:46:12
【问题描述】:

所以我这里有这段代码:

final CriteriaBuilder builder = JPA.em().getCriteriaBuilder();
    final CriteriaQuery<Ticket> criteria = builder.createQuery(Ticket.class);
    Root<Ticket> ticketRoot = criteria.from(Ticket.class);
    Join<Ticket, Order> order = ticketRoot.join("order", JoinType.LEFT);
    Join<Ticket, EventGroup> eventGroups = ticketRoot.join("eventGroup", JoinType.LEFT);
    final List<javax.persistence.criteria.Predicate> predicates = new ArrayList<>();


if (from != null) {
    predicates.add(
        builder.or(
            builder.greaterThanOrEqualTo(order.get("completedOn"), from),
            builder.greaterThanOrEqualTo(ticketRoot.get("refundedAt"), from)
        )
    );
}

它现在查找日期为completedOnrefundedAt 且日期在from 之后的票证。我想改变它。

我现在想要的是以下内容: 如果票证的refundedAt 不是 null,则获取日期在from 之后的refundedAt,否则获取日期在from 之后的completedOn

我尝试使用builder.selectCase(),也与criteria.multiSelect() 结合使用,但没有成功。

我希望有人可以帮助我。

编辑: 为了说明目前的情况,下面解释一下 if/else 语句:

如果 refundedAt 不为空,仅当refundedAtfrom 之后才获得票证。

ELSErefundedAt 为空)仅当 completedOn 位于 from 之后时才能获得票证。

【问题讨论】:

  • 您可能正在寻找 Java 三元运算符 - tutorials.jenkov.com/java/ternary-operator.html
  • 我尝试执行以下操作:predicates.add(ticketRoot.get("refundedAt") == null ? builder.greaterThanOrEqualTo(order.get("completedOn"), from) : builder.greaterThanOrEqualTo(ticketRoot.get("refundedAt"), from) ); 它不会抛出错误,但创建的查询不正确。

标签: java jpa criteria predicate


【解决方案1】:

使用andor

predicates.add(
    builder.or(
        builder.and(    
            builder.isNotNull(ticketRoot.get("refundedAt")),        
            builder.greaterThanOrEqualTo(ticketRoot.get("refundedAt"), from)
        ),
        builder.and(            
            builder.isNull(ticketRoot.get("refundedAt")), 
            builder.greaterThanOrEqualTo(order.get("completedOn"), from)
        )
    )
);    

【讨论】:

  • 问题是这不起作用。 predicates 所需的类型是 PredicateselectCase() 返回 Expression&lt;java.lang.Object&gt;
  • @TBatist 因为greaterThanOrEqualTo返回一个谓词,否则的返回值可能是Expression&lt;Boolean&gt;,它是一个谓词。不确定,但如果您添加投射 (Predicate) builder.selectCase() 可能会起作用
  • 是的,我也是这么想的,但是它给出了一个错误;不可转换的类型。所以我不能施放它。
  • @TBatist 我已经更新了答案->您需要使用asExpression&lt;Object&gt; 转换为Expression&lt;Boolean&gt;,然后您可以转换为谓词
  • 不幸的是,这会引发ClassCastException。所以它确实编译了,但它在运行时抛出了它。 (SearchedCaseExpression 不能转换为 Predicate)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多