两个LocalDateTime之间的标准API依时间排序

时间:2019-02-11 12:40:12

标签: jpa eclipselink criteria-api

给出一个具有两个日期类型为LocalDateTime的实体:

class MyEntity {

    private LocalDateTime start;
    private LocalDateTime lastUpdate;

}

我想编写一个带有条件api的查询,该查询按这两个日期之间的时间对结果集进行排序。

/* ... */
Root<MyEntity> root = query.from(MyEntity.class);
Order order = ???
root.orderBy(cb.desc(order));
/* ... */

到目前为止我的想法:

  • CriteriaBuilder#diff希望其参数来自Number,而LocalDateTime则不是
  • CriteriaBuilder#treat可能以某种方式将其视为时间戳记?毕竟它是作为时间戳存储在数据库中的

p.s .:

  • 使用EclipseLink 2.7.3
  • 寻找不依赖于特定数据库的解决方案

1 个答案:

答案 0 :(得分:1)

您的cb.treat(..)想法会失败,因为Number不扩展/继承LocalDateTime。而且即使有可能也会出现问题,因为没有办法直接在数据库端将数据库timestamp类型转换为任何Number类型。

我发现this question可能会对您有所帮助。接受的答案使用标准(?)SQL函数TIMESTAMPDIFF,并且应该完全独立于实现。您可以根据该答案进行一些通用排序。

但是,一种选择是为持续时间/间隔添加新的计算字段,例如:

private Duration duration;

@PrePersist // update on each persist
private void calcDuration() {
    duration = Duration.between(start, lastUpdate);
}

然后排序如下:

Path<Long> duration = root.get("duration");  // duration is stored as bigint or like
criteriaQuery.orderBy(criteriaBuilder.desc(duration)); // or .asc(..)

自然duration会占用db中的额外空间-通常它应该只是瞬时值和/或计算值-但也可能会带来一些性能提升。