如何在 JPA 查询中将日期时间转换为日期
Posted
技术标签:
【中文标题】如何在 JPA 查询中将日期时间转换为日期【英文标题】:How to convert Datetime to Date in JPA query 【发布时间】: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 上运行,使用不同的数据库。
【问题讨论】:
【参考方案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 字段包含时间信息,但我可以查询后处理。 对风格感到抱歉,*** 在评论中的降价很糟糕。 有两件事要说。首先是您可以尝试转换为日期,正如我在编辑中提到的那样。二是如果你认为我的回答是对的,那你能接受吗? 转换不起作用,这是一个非法的ArgumentException,但substring
在group by
子句中工作,这是导入的东西,给了我正确的结果,我仍在寻找更好的方法。跨度>
【参考方案2】:
您有两种可能的解决方案:
-
将对象 StatisticsPair 中的 LocalDateTime 更改为具有 LocalDate 而不是 LocalDateTime,希望 Spring JPA 仅采用日期组件:
....
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StatisticsPair
private LocalDate date;
private BigDecimal balance;
-
第二种解决方案是在 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:05
和 2006-01-02
都可以映射到 LocalDateTime
。
只是你可以使用 LocalDate 作为参数。 JPA 引擎应该负责其余的工作。
查看底部最后的更新,只需更改参数,JPA会处理。以上是关于如何在 JPA 查询中将日期时间转换为日期的主要内容,如果未能解决你的问题,请参考以下文章