JPA - 返回 StartDate 之后和 EndDate 之前的实体

Posted

技术标签:

【中文标题】JPA - 返回 StartDate 之后和 EndDate 之前的实体【英文标题】:JPA - Returning entities that are After StartDate and Before EndDate 【发布时间】:2018-06-02 16:02:16 【问题描述】:

我的实体中有两个日期。即。

Date startDate;
Date endDate;

如何查询,以便给定日期,它将返回指定日期在startDateendDate 之间的所有实体?

我已经尝试了以下方法:

findByStartDateAfterAndEndDateBefore(Date givenDate);

Spring-Data-JPA 不喜欢这样并遇到错误。没有具体的错误,repo 就是无法注入到我的班级中。

正确的方法是什么?我知道这可以通过 Hibernate 标准或使用 Native SQL 轻松完成,但尝试在 Spring JPA 中做到这一点。

这是查询本身的问题还是 Spring 使用的日期类型之间的某种不兼容?

尝试了findByStartDateAfterAndEndDateBefore(Date givenDate, Date givenDate),但返回 null。

【问题讨论】:

findByStartDate... JPA didnt like this。 JPA 不喜欢它是有原因的; JPA API 与开始 findXXX 的方法没有任何关系。那就是 Spring Data JPA API。完全不同的 API @DN1 是的,标记为 Spring JPA api。无论如何感谢您的编辑。 您检查的startDateendDate 字段是否只是日期,还是包含时间数据? @Just date 很好。我真的不需要时间。 00:00:00 很好。 您使用的是什么版本的 Spring Data JPA? Date 的确切类型是什么?是java.sql.Date 还是java.util.Date 【参考方案1】:

您在 JPA 查询中使用了AND 条件,但只提供了一个参数。你应该使用findByStartDateAfterAndEndDateBefore(Date startDate, Date endDate);

【讨论】:

我想要介于给定日期之间的记录。 在什么给定日期之间?要获得“介于”数据,您必须有两个日期 我需要的是相反的情况。我给出了日期,并且需要所有实体,开始日期 > 给定日期和 好的,在这种情况下,您可以在两个参数中传递相同的日期值。喜欢findByStartDateAfterAndEndDateBefore(Date givenDate, Date givenDate) 或者创建一个默认的方法来为你做这件事。【参考方案2】:

令我惊讶的是,LessThanGreaterThan 工作,BeforeAfter 严重失败。

我从没想过我可以使用小于和大于来表示日期,并且总是查看与日期相关的函数,例如介于、之前、之后。

这主要是因为文档示例

After

findByStartDateAfter

… where x.startDate > ?1

Before

findByStartDateBefore

… where x.startDate < ?1

所以我更仔细地查看了Spring Data JPA 的文档,并通过以下示例发现了一些有趣的东西

 LocalDate date = new LocalDate().minusYears(2);
 return builder.lessThan(root.get(_Customer.createdAt), date);

因此,在比较数据时间时,作者使用标准lessthan 作为时间属性。

所以给了一个小于和工作的镜头,然后又给了一个大于的镜头,然后一起。于是我得出了一个结论

public MyDateEntity findByStartDateLessThanAndEndDateGreaterThan(Date sDate, Date eDate); 

到目前为止,这是有效的。而且我相信,必须有一种干净的方式来处理日期,可能是before,after,between,但我就是想不通。

如果有人能解决这个问题会很棒。

【讨论】:

【参考方案3】:

由于 Spring Data 的限制,您不能只使用一个参数,但您可以使用如下代码解决它:

List<AnEntity> findByStartDateBeforeAndEndDateAfter(Date startDate, Date endDate);

default List<AnEntity> findByStartDateBeforeAndEndDateAfter(Date givenDate) 
    return findByStartDateBeforeAndEndDateAfter(givenDate, givenDate);

此代码应满足您的需求。我还使用 Spring Boot 1.5.9 对其进行了验证。使用spring-data-get-started example。

【讨论】:

我已经在我的问题中提到我尝试过使用findByStartDateAfterAndEndDateBefore(Date givenDate, Date givenDate) 正如我在答案中提到的,这是工作代码,它遵循文档,我在真实示例中对其进行了验证。试试复制粘贴吧,可能是你检查的时候打错了。 @ꜱᴜʀᴇꜱʜᴀᴛᴛᴀ 问题可能是您在方法名称中交换了“After”和“Before”谓词吗?方法名必须是 findByStartDateBeforeAndEndDateAfter 正如我所说,它返回空。然而小于和大于的作品..看起来很奇怪。 如果给定的日期相同,结果会怎样。【参考方案4】:

由于您只需要 Date 对象作为 LocalDate 的等价物,这应该可以解决问题。

default List<AnEntity> findByStartDateAfterAndEndDateBefore(Date startDate, Date endDate) 
    Calendar cal = Calendar.getInstance();
    cal.setTime(endDate);
    cal.add(Calendar.DATE, -1);
    return findByStartDateBetween(startDate, cal.getTime());

因为您希望它包含开头,但不包含结尾,并且 SQL BETWEEN 包含在内,我们只需将结尾移回一天。

【讨论】:

【参考方案5】:
    Public List<EntityClass> findData(Date startDate,Date endDate)
   
     Query<EntityClass> _q = em.createQuery("select a.* from _tableName a 
                         where a.startDate>= :d1 AND a.endDate<= :d2");
    _q.setParameter("d1", startDate, TemporalType.DATE);
    _q.setParameter("d2", endDate, TemporalType.DATE);
    List<EntityClass> result = query.getResultList();
    em.getTransaction().commit();
    return result;
   

【讨论】:

【参考方案6】:

我使用它没有这样的问题:

findAllByEntityNotNullAndDateBetween(Date begin, Date end);

你试过了吗?

【讨论】:

不是一个日期,我必须检查开始和结束日期。考虑再读一遍问题?

以上是关于JPA - 返回 StartDate 之后和 EndDate 之前的实体的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Spring Data JPA Repository 上的 save() 之后使用返回的实例?

jpa执行mysql报空指针

根据当前日期+时间查询 JPA 实体以获取实例的最佳方法是啥?

JPA EntiityManager.find方法

Spring JPA Repository findAll 在 JUnit 测试中不返回任何数据

SQL 日期过滤器:当开始日期 = 结束日期时返回结果