【问题标题】:How to convert Datetime to Date in JPA query如何在 JPA 查询中将日期时间转换为日期
【发布时间】:2019-01-23 10:55:06
【问题描述】:

我正在使用 Spring data JPA 编写复杂的查询,比如说统计查询。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StatisticsPair {
  private LocalDateTime time;
  private BigDecimal balance;
}

@Data
@Entity
@Table(name="t_order")
public class Order {
  private LocalDateTime createdTime;
  private BigDecimal amount;
  private OrderStatus status;
}

在存储库中查询:

@Query("select new xxx.StatisticsPair(createdTime, sum(amount)) from Order where createdTime >= ?1 and createdTime <= ?2 and status = xxx.OrderStatus.COMPLETED group by createdTime")
List<StatisticsPair> statAmountByDay(LocalDateTime from, LocalDateTime to);

方法statAmountByDay 给了我这样的结果:

[
  {"time": "2006-01-02 15:04:05", "balance": 100.00}
  {"time": "2006-01-02 16:04:05", "balance": 200.00}
  {"time": "2006-01-03 15:04:05", "balance": 200.00}
]

但我要按天统计,只需要日期,时间没用,预期结果:

[
  {"time": "2006-01-02", "balance": 300.00}
  {"time": "2006-01-03", "balance": 200.00}
]

所以我想知道如何将createdTime(datetime type) 转换为Date 类型,就像mysql 中的函数DATE(createdTime),但我不想使用本机查询,因为我的代码在不同的ENV 上运行,使用不同的数据库。

【问题讨论】:

    标签: java spring jpa spring-data-jpa spring-data


    【解决方案1】:

    我知道这不是最好的方法,但在我找到更好的解决方案之前,您可以将返回的时间作为字符串处理(使用 SUBSTRING

    xxx.StatisticsPair(substring(cast(createdTime as nvarchar(19)), 1, 10), sum(amount))

    或尝试:

    xxx.StatisticsPair(cast(createdTime as date), sum(amount))

    【讨论】:

    • 受你的启发,它现在可以工作了,但我仍在寻找一种优雅的方式,我认为可能是 SpEL 可以提供帮助。 ` @Query("select new xxx.StatisticsPair(createdTime, sum(amount)) from Order where createdTime >= ?1 and createdTime time 字段包含时间信息,但我可以查询后处理。
    • 对风格感到抱歉,stackoverflow 在评论中的降价很糟糕。
    • 有两件事要说。首先是您可以尝试转换为日期,正如我在编辑中提到的那样。二是如果你认为我的回答是对的,那你能接受吗?
    • 转换不起作用,这是一个非法的ArgumentException,但substringgroup by 子句中工作,这是导入的东西,给了我正确的结果,我仍在寻找更好的方法。跨度>
    【解决方案2】:

    您有两种可能的解决方案:

    1. 将对象 StatisticsPair 中的 LocalDateTime 更改为具有 LocalDate 而不是 LocalDateTime,希望 Spring JPA 仅采用日期组件:

    ....

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class StatisticsPair {
        private LocalDate date;
        private BigDecimal balance;
    }
    
    1. 第二种解决方案是在 StatisticsPair 列表上使用 java 和 java 流进行操作:

    ....

    List<StatisticsPair> list = ... ;
    List<StatisticsPairWithDate> listWithDate;
    listWithDate = list
                .stream()
                .map(sp-> 
                        new StatisticsPairWithDate(
                                sp.getTime().toLocalDate(), 
                                sp.getBalance()))
                .collect(Collectors.toList()); 
    

    ....

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class StatisticsPairWithDate {
      private LocalDate date;
      private BigDecimal balance;
    }
    

    ==============================================

    @Query("select new xxx.StatisticsPair(createdTime, sum(amount)) from Order where createdTime >= ?1 and createdTime <= ?2 and status = xxx.OrderStatus.COMPLETED group by createdTime")
    List<StatisticsPair> statAmountByDay(LocalDate from, LocalDate to);
    

    【讨论】:

    • 我想你误解了我,这不是关于结果,而是关于我传递给数据库的参数。对于结果 2006-01-02 15:04:052006-01-02 都可以映射到 LocalDateTime
    • 只是你可以使用 LocalDate 作为参数。 JPA 引擎应该负责其余的工作。
    • 查看底部最后的更新,只需更改参数,JPA会处理。
    猜你喜欢
    • 1970-01-01
    • 2011-06-12
    • 2011-04-14
    • 2010-11-03
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    相关资源
    最近更新 更多