Перейти к основному содержимому

Запрос объектов по дате и времени с помощью Spring Data JPA

· 4 мин. чтения

1. Введение

В этом кратком руководстве мы увидим, как запрашивать объекты по датам с помощью Spring Data JPA.

Во-первых, мы освежим нашу память о том, как отображать дату и время с помощью JPA. Затем мы создадим объект с полями даты и времени, а также репозиторий Spring Data для запроса этих объектов.

2. Сопоставление дат и времени с помощью JPA

Для начала мы рассмотрим немного теории об отображении дат с помощью JPA . Важно знать, что нам нужно решить, хотим ли мы представлять:

  • Только свидание
  • Только время
  • Или оба

В дополнение к (необязательной) аннотации @Column нам нужно добавить аннотацию @Temporal , чтобы указать, что представляет поле.

Эта аннотация принимает параметр, являющийся значением перечисления TemporalType:

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

Подробную статью о отображении даты и времени с помощью JPA можно найти здесь .

3. На практике

На практике, как только наши объекты правильно настроены, не так много работы, чтобы запросить их с помощью Spring Data JPA. Нам просто нужно использовать методы запроса или аннотацию @Query .

Каждый механизм Spring Data JPA будет работать нормально .

Давайте посмотрим на пару примеров объектов, запрашиваемых по дате и времени с помощью Spring Data JPA.

3.1. Настройка объекта

Например, предположим, что у нас есть объект Article с датой публикации, временем публикации, а также датой и временем создания:

@Entity
public class Article {

@Id
@GeneratedValue
Integer id;

@Temporal(TemporalType.DATE)
Date publicationDate;

@Temporal(TemporalType.TIME)
Date publicationTime;

@Temporal(TemporalType.TIMESTAMP)
Date creationDateTime;
}

Мы разделили дату и время публикации на два поля в демонстрационных целях; таким образом мы представляем три временных типа.

3.2. Запрос сущностей

Теперь, когда наша сущность настроена, давайте создадим репозиторий Spring Data для запроса этих статей.

Мы создадим три метода, используя несколько функций 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);

}

Итак, мы определили три метода:

  • findAllByPublicationDate , который извлекает статьи, опубликованные в указанную дату.
  • findAllByPublicationTimeBetween , который извлекает статьи, опубликованные между двумя заданными часами .
  • и findAllWithCreationDateTimeBefore , который извлекает статьи, созданные до указанной даты и времени.

Первые два метода основаны на механизме методов запросов Spring Data , а последний — на аннотации @Query .

В конце концов, это не меняет способа обработки дат. Первый метод будет рассматривать только часть даты параметра.

Второй будет учитывать только время параметров. И последний будет использовать и дату, и время.

3.3. Протестируйте запросы

Последнее, что мы сделаем, — настроим несколько тестов, чтобы убедиться, что эти запросы работают должным образом.

Сначала мы импортируем данные в нашу базу данных, а затем создадим тестовый класс, который будет проверять каждый метод репозитория:

@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));
}
}

Каждый тест проверяет, что извлекаются только те статьи, которые соответствуют условиям.

4. Вывод

В этой краткой статье мы узнали, как запрашивать объекты по их полям даты и времени с помощью Spring Data JPA.

Мы обсудили немного теории, прежде чем использовать механизмы Spring Data для запроса сущностей. Мы видели, что эти механизмы работают с датами и временем так же, как и с другими типами данных.

Исходный код этой статьи доступен на GitHub .