JPA でインメモリ H2 データアクセス

このガイドでは、Spring Data JPA を使用してリレーショナルデータベースにデータを保存および取得するアプリケーションを構築するプロセスを順を追って説明します。

構築するもの

Customer POJO(Plain Old Java Objects)をメモリベースのデータベースに保存するアプリケーションを構築します。

必要なもの

本ガイドの完成までの流れ

ほとんどの Spring 入門ガイドと同様に、最初から始めて各ステップを完了するか、すでに慣れている場合は基本的なセットアップステップをバイパスできます。いずれにしても、最終的に動作するコードになります。

最初から始めるには、Spring Initializr から開始に進みます。

基本スキップするには、次の手順を実行します。

完了したときは、gs-accessing-data-jpa/complete のコードに対して結果を確認できます。

Spring Initializr から開始

IDE を使用する場合はプロジェクト作成ウィザードを使用します。IDE を使用せずにコマンドラインなどで開発する場合は、この事前に初期化されたプロジェクトからプロジェクトを ZIP ファイルとしてダウンロードできます。このプロジェクトは、このチュートリアルの例に合うように構成されています。

プロジェクトを手動で初期化するには:

  1. IDE のメニューまたはブラウザーから Spring Initializr を開きます。アプリケーションに必要なすべての依存関係を取り込み、ほとんどのセットアップを行います。

  2. Gradle または Maven のいずれかと、使用する言語を選択します。このガイドは、Java を選択したことを前提としています。

  3. 依存関係をクリックし、Spring Data JPAH2 Database の順に選択します。

  4. 生成をクリックします。

  5. 結果の ZIP ファイルをダウンロードします。これは、選択して構成された Web アプリケーションのアーカイブです。

EclipseIntelliJ のような IDE は新規プロジェクト作成ウィザードから Spring Initializr の機能が使用できるため、手動での ZIP ファイルのダウンロードやインポートは不要です。
プロジェクトを Github からフォークして、IDE または他のエディターで開くこともできます。

単純なエンティティを定義する

この例では、Customer オブジェクトを保存し、それぞれに JPA エンティティとしてアノテーションを付けます。次のリストは、Customer クラス(src/main/java/com/example/accessingdatajpa/Customer.java 内)を示しています。

package com.example.accessingdatajpa;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Customer {

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Long id;
  private String firstName;
  private String lastName;

  protected Customer() {}

  public Customer(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  @Override
  public String toString() {
    return String.format(
        "Customer[id=%d, firstName='%s', lastName='%s']",
        id, firstName, lastName);
  }

  public Long getId() {
    return id;
  }

  public String getFirstName() {
    return firstName;
  }

  public String getLastName() {
    return lastName;
  }
}

ここに、idfirstNamelastName という 3 つの属性を持つ Customer クラスがあります。また、2 つのコンストラクターがあります。デフォルトのコンストラクターは、JPA のためにのみ存在します。直接使用しないため、protected と表記します。もう 1 つのコンストラクターは、データベースに保存する Customer のインスタンスを作成するために使用するコンストラクターです。

Customer クラスには @Entity のアノテーションが付けられており、JPA エンティティであることを示しています。(@Table アノテーションが存在しないため、このエンティティは Customer という名前のテーブルにマッピングされると想定されます。)

Customer オブジェクトの id プロパティには @Id のアノテーションが付けられているため、JPA はそれをオブジェクトの ID として認識します。id プロパティにも @GeneratedValue のアノテーションが付けられ、ID が自動的に生成されることを示します。

他の 2 つのプロパティ firstName と lastName にはアノテーションが付けられていません。これらは、プロパティ自体と同じ名前を共有する列にマップされると想定されています。

便利な toString() メソッドは、顧客のプロパティを出力します。

単純なクエリを作成する

Spring Data JPA は、JPA を使用してリレーショナルデータベースにデータを保存することに焦点を当てています。その最も魅力的な機能は、実行時にリポジトリインターフェースからリポジトリ実装を自動的に作成する機能です。

これがどのように機能するかを確認するには、次のリスト(src/main/java/com/example/accessingdatajpa/CustomerRepository.java 内)が示すように、Customer エンティティで動作するリポジトリインターフェースを作成します。

package com.example.accessingdatajpa;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface CustomerRepository extends CrudRepository<Customer, Long> {

  List<Customer> findByLastName(String lastName);

  Customer findById(long id);
}

CustomerRepository は、CrudRepository インターフェースを継承します。エンティティの型とそれが機能する ID、Customer および Long は、CrudRepository のジェネリクスパラメーターで指定されます。CrudRepository を継承することにより、CustomerRepository は、Customer エンティティを保存、削除、検索する方法など、Customer 永続性を操作するためのいくつかの方法を継承します。

Spring Data JPA では、メソッドシグネチャーを宣言することにより、他のクエリメソッドを定義することもできます。例: CustomerRepository には findByLastName() メソッドが含まれています。

典型的な Java アプリケーションでは、CustomerRepository を実装するクラスを作成することを期待できます。ただし、それが Spring Data JPA を非常に強力にしている理由です。リポジトリインターフェースの実装を記述する必要はありません。Spring Data JPA は、アプリケーションの実行時に実装を作成します。

これで、この例を接続して、その外観を確認できます!

アプリケーションクラスを作成する

Spring Initializr は、アプリケーションの単純なクラスを作成します。次のリストは、Initializr がこの例(src/main/java/com/example/accessingdatajpa/AccessingDataJpaApplication.java 内)で作成したクラスを示しています。

package com.example.accessingdatajpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AccessingDataJpaApplication {

  public static void main(String[] args) {
    SpringApplication.run(AccessingDataJpaApplication.class, args);
  }

}

@SpringBootApplication は、次のすべてを追加する便利なアノテーションです。

  • @Configuration: アプリケーションコンテキストの Bean 定義のソースとしてクラスにタグを付けます。

  • @EnableAutoConfiguration: クラスパス設定、他の Bean、さまざまなプロパティ設定に基づいて Bean の追加を開始するよう Spring Boot に指示します。例: spring-webmvc がクラスパスにある場合、このアノテーションはアプリケーションに Web アプリケーションとしてフラグを立て、DispatcherServlet のセットアップなどの主要な動作をアクティブにします。

  • @ComponentScan: Spring に、com/example パッケージ内の他のコンポーネント、構成、サービスを探して、コントローラーを検出させるように指示します。

main() メソッドは、Spring Boot の SpringApplication.run() メソッドを使用してアプリケーションを起動します。XML が 1 行もないことに気付きましたか? web.xml ファイルもありません。この Web アプリケーションは 100% 純粋な Java であり、接続機能やインフラストラクチャの構成に対処する必要はありませんでした。

ここで、Initializr が作成した単純なクラスを変更する必要があります。出力を取得するには(この例ではコンソールに)、ロガーをセットアップする必要があります。次に、いくつかのデータを設定し、それを使用して出力を生成する必要があります。次のリストは、完成した AccessingDataJpaApplication クラス(src/main/java/com/example/accessingdatajpa/AccessingDataJpaApplication.java 内)を示しています。

package com.example.accessingdatajpa;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class AccessingDataJpaApplication {

  private static final Logger log = LoggerFactory.getLogger(AccessingDataJpaApplication.class);

  public static void main(String[] args) {
    SpringApplication.run(AccessingDataJpaApplication.class);
  }

  @Bean
  public CommandLineRunner demo(CustomerRepository repository) {
    return (args) -> {
      // save a few customers
      repository.save(new Customer("Jack", "Bauer"));
      repository.save(new Customer("Chloe", "O'Brian"));
      repository.save(new Customer("Kim", "Bauer"));
      repository.save(new Customer("David", "Palmer"));
      repository.save(new Customer("Michelle", "Dessler"));

      // fetch all customers
      log.info("Customers found with findAll():");
      log.info("-------------------------------");
      repository.findAll().forEach(customer -> {
        log.info(customer.toString());
      });
      log.info("");

      // fetch an individual customer by ID
      Customer customer = repository.findById(1L);
      log.info("Customer found with findById(1L):");
      log.info("--------------------------------");
      log.info(customer.toString());
      log.info("");

      // fetch customers by last name
      log.info("Customer found with findByLastName('Bauer'):");
      log.info("--------------------------------------------");
      repository.findByLastName("Bauer").forEach(bauer -> {
        log.info(bauer.toString());
      });
      log.info("");
    };
  }

}

AccessingDataJpaApplication クラスには、CustomerRepository をいくつかのテストにかける demo() メソッドが含まれています。まず、Spring アプリケーションコンテキストから CustomerRepository をフェッチします。次に、Customer オブジェクトをいくつか保存して、save() メソッドを示し、操作するデータを設定します。次に、findAll() を呼び出して、データベースからすべての Customer オブジェクトをフェッチします。次に、findById() を呼び出して、その ID で単一の Customer をフェッチします。最後に、findByLastName() を呼び出して、姓が "Bauer" であるすべての顧客を検索します。demo() メソッドは、アプリケーションの起動時にコードを自動的に実行する CommandLineRunner Bean を返します。

デフォルトでは、Spring Boot は JPA リポジトリのサポートを有効にし、@SpringBootApplication が存在するパッケージ(およびそのサブパッケージ)を検索します。構成の JPA リポジトリインターフェース定義が表示されていないパッケージにある場合、@EnableJpaRepositories とその型安全 basePackageClasses=MyRepository.class パラメーターを使用して代替パッケージを指定できます。

実行可能 JAR を構築する

コマンドラインから Gradle または Maven を使用してアプリケーションを実行できます。必要なすべての依存関係、クラス、リソースを含む単一の実行可能 JAR ファイルを構築して実行することもできます。実行可能な jar を構築すると、開発ライフサイクル全体、さまざまな環境などで、アプリケーションとしてサービスを簡単に提供、バージョン管理、デプロイできます。

Gradle を使用する場合、./gradlew bootRun を使用してアプリケーションを実行できます。または、次のように、./gradlew build を使用して JAR ファイルをビルドしてから、JAR ファイルを実行できます。

java -jar build/libs/gs-accessing-data-jpa-0.1.0.jar

Maven を使用する場合、./mvnw spring-boot:run を使用してアプリケーションを実行できます。または、次のように、./mvnw clean package で JAR ファイルをビルドしてから、JAR ファイルを実行できます。

java -jar target/gs-accessing-data-jpa-0.1.0.jar
ここで説明する手順は、実行可能な JAR を作成します。クラシック WAR ファイルを作成することもできます。

アプリケーションを実行すると、次のような出力が表示されます。

== Customers found with findAll():
Customer[id=1, firstName='Jack', lastName='Bauer']
Customer[id=2, firstName='Chloe', lastName='O'Brian']
Customer[id=3, firstName='Kim', lastName='Bauer']
Customer[id=4, firstName='David', lastName='Palmer']
Customer[id=5, firstName='Michelle', lastName='Dessler']

== Customer found with findById(1L):
Customer[id=1, firstName='Jack', lastName='Bauer']

== Customer found with findByLastName('Bauer'):
Customer[id=1, firstName='Jack', lastName='Bauer']
Customer[id=3, firstName='Kim', lastName='Bauer']

要約

おめでとう! 具体的なリポジトリ実装を作成せずに、Spring Data JPA を使用してオブジェクトをデータベースに保存したり、データベースからフェッチしたりする単純なアプリケーションを作成しました。

ハイパーメディアベースの RESTful フロントエンドで JPA リポジトリを簡単に公開したい場合は、Spring Data REST API の自動生成 (JPA) を読むことをお勧めします。

関連事項

次のガイドも役立つかもしれません:

新しいガイドを作成したり、既存のガイドに貢献したいですか? 投稿ガイドラインを参照してください [GitHub] (英語)

すべてのガイドは、コード用の ASLv2 ライセンス、およびドキュメント用の Attribution、NoDerivatives creative commons ライセンス (英語) でリリースされています。

コードを入手する

FREE

クラウドでの作業

Spring アカデミーのクラウドでガイドを完成させよう。

Spring アカデミーへ

プロジェクト