1. 序章

このクイックチュートリアルでは、Spring DataJPAを使用して日付でエンティティをクエリする方法を説明します。

最初に、JPAを使用して日付と時刻をマップする方法についての記憶を更新します。 次に、日付と時刻のフィールドを持つエンティティと、それらのエンティティをクエリするためのSpring Dataリポジトリを作成します。

2. JPAを使用した日付と時刻のマッピング

まず、JPAを使用した日付のマッピングに関する理論を少し確認します。 知っておくべきことは、表現するかどうかを決定する必要があるということです。

  • 日付のみ
  • 時間だけ
  • または両方

(オプションの) @Column アノテーションに加えて、 @Temporal アノテーションを追加して、フィールドが何を表すかを指定する必要があります。

このアノテーションは、 TemporalType enum:の値であるパラメーターを取ります

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

JPAを使用した日付と時刻のマッピングに関する詳細な記事は、ここにあります。

3. 実際には

実際には、エンティティが正しく設定されると、Spring DataJPAを使用してエンティティをクエリするために行う作業はそれほど多くありません。 クエリメソッド、、または@Queryアノテーションを使用する必要があります。

すべてのSpringDataJPAメカニズムは正常に機能します

Spring DataJPAを使用して日付と時刻でクエリされたエンティティの例をいくつか見てみましょう。

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

デモンストレーションの目的で、発行日時を2つのフィールドに分割しました。 このようにして、3つの時間タイプを表します。

3.2. エンティティをクエリする

エンティティがすべて設定されたので、Spring Dataリポジトリを作成してこれらの記事をクエリします。

いくつかのSpring DataJPA機能を使用して3つのメソッドを作成します。

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

}

そこで、次の3つの方法を定義しました。

  • findAllByPublicationDate は、特定の日付に公開された記事を取得します
  • findAllByPublicationTimeBetween は、指定された2時間の間に公開された記事を取得します
  • findAllWithCreationDateTimeBefore は、指定された日時より前に作成された記事を取得します

最初の2つのメソッドは、Spring Dataのクエリメソッドメカニズムに依存し、最後の2つのメソッドは@Queryアノテーションに依存します。

結局、それは日付の扱い方を変えるものではありません。 最初の方法では、パラメーターの日付部分のみが考慮されます。

2つ目は、パラメーターの時間のみを考慮します。 そして最後は日付と時刻の両方を使用します。

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 DataJPAを使用して日付と時刻のフィールドでエンティティをクエリする方法を学びました。

Spring Dataメカニズムを使用してエンティティをクエリする前に、少し理論について説明しました。 これらのメカニズムは、他のタイプのデータと同じように日付と時刻で機能することがわかりました。

この記事のソースコードは、GitHubから入手できます。