Query Entities by Dates and Times with Spring Data JPA – 用Spring Data JPA按日期和时间查询实体

最后修改: 2018年 7月 23日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this quick tutorial, we’ll see how to query entities by dates with Spring Data JPA.

在这个快速教程中,我们将看到如何用Spring Data JPA按日期查询实体。

First, we’ll refresh our memory on how to map dates and times with JPA. Then we’ll create an entity with date and time fields, as well as a Spring Data repository to query those entities.

首先,我们将回顾一下如何用JPA来映射日期和时间。然后我们将创建一个带有日期和时间字段的实体,以及一个用于查询这些实体的Spring Data资源库。

2. Mapping Dates and Times with JPA

2.用JPA映射日期和时间

To begin, we’ll review a bit of theory about mapping dates with JPA. The thing to know is that we need to decide whether we want to represent:

首先,我们将回顾一下关于用JPA映射日期的一些理论。要知道的是,我们需要决定是否要表示。

  • A date only
  • A time only
  • Or both

In addition to the (optional) @Column annotation, we’ll need to add the @Temporal annotation to specify what the field represents.

除了(可选的)@Column注解,我们还需要添加@Temporal注解来指定字段代表的内容。

This annotation takes a parameter that’s a value of TemporalType enum:

该注解接受一个参数,该参数是TemporalType枚举的值:

  • TemporalType.DATE
  • TemporalType.TIME
  • TemporalType.TIMESTAMP

A detailed article about date and time mapping with JPA can be found here.

关于JPA的日期和时间映射的详细文章可以在这里找到。

3. In Practice

3.在实践中

In practice, once our entities are correctly set up, there’s not much work to do to query them using Spring Data JPA. We just have to use query methods, or the @Query annotation.

在实践中,一旦我们的实体被正确设置,使用Spring Data JPA来查询它们就没有太多的工作要做。我们只需使用查询方法,@Query 注解。

Every Spring Data JPA mechanism will work just fine.

每个Spring Data JPA机制都能正常工作

Let’s see a couple examples of entities queried by dates and times with Spring Data JPA.

让我们看看用Spring Data JPA按日期和时间查询实体的几个例子。

3.1. Set Up an Entity

3.1.建立一个实体

For instance, let’s say we have an Article entity with a publication date, publication time, and a creation date and time:

例如,假设我们有一个文章实体,有一个出版日期、出版时间和创建日期和时间。

@Entity
public class Article {

    @Id
    @GeneratedValue
    Integer id;
 
    @Temporal(TemporalType.DATE)
    Date publicationDate;
 
    @Temporal(TemporalType.TIME)
    Date publicationTime;
 
    @Temporal(TemporalType.TIMESTAMP)
    Date creationDateTime;
}

We split the publication date and time into two fields for demonstration purposes; that way we represent the three temporal types.

为了演示,我们将出版日期和时间分成两个字段;这样我们就能代表三种时间类型。

3.2. Query the Entities

3.2.查询实体

Now that our entity is all set up, let’s create a Spring Data repository to query those articles.

现在,我们的实体已经设置好了,让我们创建一个Spring Data资源库来查询这些文章。

We’ll create three methods using several Spring Data JPA features:

我们将使用Spring Data JPA的几个特性创建三个方法。

public interface ArticleRepository 
  extends JpaRepository<Article, Integer> {

    List<Article> findAllByPublicationDate(Date publicationDate);

    List<Article> findAllByPublicationTimeBetween(
      Date publicationTimeStart,
      Date publicationTimeEnd);

    @Query("select a from Article a where a.creationDateTime <= :creationDateTime")
    List<Article> findAllWithCreationDateTimeBefore(
      @Param("creationDateTime") Date creationDateTime);

}

So we defined three methods:

所以我们定义了三种方法。

  • findAllByPublicationDate which retrieves articles published on a given date
  • findAllByPublicationTimeBetween which retrieves articles published between two given hours
  • and findAllWithCreationDateTimeBefore which retrieves articles created before a given date and time

The first two methods rely on Spring Data’s query methods mechanism, and the last on the @Query annotation.

前两种方法依赖于Spring Data的查询方法机制,最后一种依赖于@Query注解。

In the end, that doesn’t change the way dates will be treated. The first method will only consider the date part of the parameter.

最终,这并没有改变处理日期的方式。第一个方法将只考虑参数中的日期部分。

The second will only consider the time of the parameters. And the last will use both date and time.

第二个将只考虑参数的时间。而最后一个将同时使用日期和时间。

3.3. Test the Queries

3.3.测试查询

The last thing we’ll do is set up some tests to check that these queries work as expected.

我们要做的最后一件事是设置一些测试,以检查这些查询是否按预期工作。

We’ll first import data into our database, and then we’ll create the test class that’ll check each method of the repository:

我们首先将数据导入数据库,然后创建测试类,检查资源库的每个方法。

@RunWith(SpringRunner.class)
@DataJpaTest
public class ArticleRepositoryIntegrationTest {

    @Autowired
    private ArticleRepository repository;

    @Test
    public void whenFindByPublicationDate_thenArticles1And2Returned() {
        List<Article> result = repository.findAllByPublicationDate(
          new SimpleDateFormat("yyyy-MM-dd").parse("2018-01-01"));

        assertEquals(2, result.size());
        assertTrue(result.stream()
          .map(Article::getId)
          .allMatch(id -> Arrays.asList(1, 2).contains(id)));
    }

    @Test
    public void whenFindByPublicationTimeBetween_thenArticles2And3Returned() {
        List<Article> result = repository.findAllByPublicationTimeBetween(
          new SimpleDateFormat("HH:mm").parse("15:15"),
          new SimpleDateFormat("HH:mm").parse("16:30"));

        assertEquals(2, result.size());
        assertTrue(result.stream()
          .map(Article::getId)
          .allMatch(id -> Arrays.asList(2, 3).contains(id)));
    }

    @Test
    public void givenArticlesWhenFindWithCreationDateThenArticles2And3Returned() {
        List<Article> result = repository.findAllWithCreationDateTimeBefore(
          new SimpleDateFormat("yyyy-MM-dd HH:mm").parse("2017-12-15 10:00"));

        assertEquals(2, result.size());
        assertTrue(result.stream()
          .map(Article::getId)
          .allMatch(id -> Arrays.asList(2, 3).contains(id));
    }
}

Each test verifies that only the articles matching the conditions are retrieved.

每个测试都验证了只有符合条件的文章被检索出来。

4. Conclusion

4.总结

In this brief article, we learned how to query entities by their dates and times fields with Spring Data JPA.

在这篇简短的文章中,我们学习了如何用Spring Data JPA通过其日期和时间字段查询实体。

We discussed a bit of theory before using Spring Data mechanisms to query the entities. We saw those mechanisms work the same way with dates and times as they do with other types of data.

在使用Spring Data机制来查询实体之前,我们讨论了一些理论。我们看到这些机制对日期和时间的工作方式与对其他类型数据的工作方式相同。

The source code for this article is available over on GitHub.

本文的源代码可在GitHub上获得