在 HQL 中查找日期之间的实体
Find entities between dates in HQL
我正在使用 HQL 和 javax.persistence
。在我的 MySQL 数据库中,我有一个日期时间(例如 2018-01-22 18:00:00
)。从客户端,我收到了一个没有时间的日期(例如 2018-01-20
)。我想找到日期时间在 startDate
和 endDate
之间的所有实体。
public List<BillingRunEntity> getBillingRuns(List<String> accountIds, LocalDate startDate, LocalDate endDate) {
String query = "SELECT DISTINCT bre " +
"FROM BillingRunEntity bre " +
"WHERE bre.accountId in :accountIds " +
"AND bre.billingDateTime BETWEEN :startDate AND :endDate";
return entityManager
.createQuery(query, BillingRunEntity.class)
.setParameter("accountIds", accountIds)
.setParameter("startDate", startDate)
.setParameter("endDate", endDate)
.getResultList();
}
我的 BillingRunEntity.java
的 billingDateTime
字段:
@Column(name = "billing_date_time")
private ZonedDateTime billingDateTime;
1) 尝试 运行 此查询会导致以下错误。考虑到我不关心时间,我该如何解决这个问题?
java.lang.IllegalArgumentException: Parameter value [2018-07-03] did not match expected type [java.time.ZonedDateTime (n/a)]
at org.hibernate.jpa.spi.BaseQueryImpl.validateBinding(BaseQueryImpl.java:874)
at org.hibernate.jpa.internal.QueryImpl.access[=12=]0(QueryImpl.java:80)
at org.hibernate.jpa.internal.QueryImpl$ParameterRegistrationImpl.bindValue(QueryImpl.java:248)
at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:620)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:180)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:49)
2) 这个查询会按我预期的方式工作吗?我不关心这里的时间 - 如果数据库有 2018-01-22 18:00:00
,我传递 2018-01-22
的 startDate
和 2018-01-23
的结束日期(甚至 2018-01-22
), 我希望能提取该记录。
假设数据库中的 ZonedDateTime
始终以 UTC 格式存储,您可以简单地转换为 LocalDate
ZoneId utc = ZoneId.of("UTC");
ZonedDateTime startTime = startDate.atStartOfDay(utc);
ZonedDateTime endTime = endDate.atStartOfDay(utc).plusDays(1).minusNanos(1);
[...]
.setParameter("startDate", startTime)
.setParameter("endDate", endTime)
minusNanos(1)
可能有点矫枉过正,但 BETWEEN
运算符在两端都包含在内。
如果您不对数据库中的所有值使用相同的时区,您可能需要深入研究 table 使用的 billing_date_time
列类型以了解它如何处理时区信息。
我正在使用 HQL 和 javax.persistence
。在我的 MySQL 数据库中,我有一个日期时间(例如 2018-01-22 18:00:00
)。从客户端,我收到了一个没有时间的日期(例如 2018-01-20
)。我想找到日期时间在 startDate
和 endDate
之间的所有实体。
public List<BillingRunEntity> getBillingRuns(List<String> accountIds, LocalDate startDate, LocalDate endDate) {
String query = "SELECT DISTINCT bre " +
"FROM BillingRunEntity bre " +
"WHERE bre.accountId in :accountIds " +
"AND bre.billingDateTime BETWEEN :startDate AND :endDate";
return entityManager
.createQuery(query, BillingRunEntity.class)
.setParameter("accountIds", accountIds)
.setParameter("startDate", startDate)
.setParameter("endDate", endDate)
.getResultList();
}
我的 BillingRunEntity.java
的 billingDateTime
字段:
@Column(name = "billing_date_time")
private ZonedDateTime billingDateTime;
1) 尝试 运行 此查询会导致以下错误。考虑到我不关心时间,我该如何解决这个问题?
java.lang.IllegalArgumentException: Parameter value [2018-07-03] did not match expected type [java.time.ZonedDateTime (n/a)]
at org.hibernate.jpa.spi.BaseQueryImpl.validateBinding(BaseQueryImpl.java:874)
at org.hibernate.jpa.internal.QueryImpl.access[=12=]0(QueryImpl.java:80)
at org.hibernate.jpa.internal.QueryImpl$ParameterRegistrationImpl.bindValue(QueryImpl.java:248)
at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:620)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:180)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:49)
2) 这个查询会按我预期的方式工作吗?我不关心这里的时间 - 如果数据库有 2018-01-22 18:00:00
,我传递 2018-01-22
的 startDate
和 2018-01-23
的结束日期(甚至 2018-01-22
), 我希望能提取该记录。
假设数据库中的 ZonedDateTime
始终以 UTC 格式存储,您可以简单地转换为 LocalDate
ZoneId utc = ZoneId.of("UTC");
ZonedDateTime startTime = startDate.atStartOfDay(utc);
ZonedDateTime endTime = endDate.atStartOfDay(utc).plusDays(1).minusNanos(1);
[...]
.setParameter("startDate", startTime)
.setParameter("endDate", endTime)
minusNanos(1)
可能有点矫枉过正,但 BETWEEN
运算符在两端都包含在内。
如果您不对数据库中的所有值使用相同的时区,您可能需要深入研究 table 使用的 billing_date_time
列类型以了解它如何处理时区信息。