package com.example.accessingdatamysql;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity // This tells Hibernate to make a table out of this class
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
JPA で MySQL データアクセス
このガイドでは、MySQL データベースに接続された Spring アプリケーションを作成するプロセスを順を追って説明します(他のほとんどのガイドや多くのサンプルアプリケーションが使用するインメモリの組み込みデータベースとは対照的です)。Spring Data JPA を使用してデータベースにアクセスしますが、これは多くの選択肢のうちの 1 つにすぎません(たとえば、プレーンな Spring JDBC を使用できます)。
構築するもの
MySQL データベースを作成し、Spring アプリケーションを構築して、新しく作成したデータベースに接続します。
MySQL は GPL でライセンスされているため、配布するプログラムバイナリも GPL を使用する必要があります。GNU General Public License (英語) を参照してください。 |
必要なもの
約 15 分
Eclipse STS や IntelliJ IDEA のような任意の IDE または VSCode のようなテキストエディター
Java 17 以降
このガイドを完了する方法
ほとんどの Spring 入門ガイドと同様に、最初から始めて各ステップを完了することも、このリポジトリ [GitHub] (英語) のコードを確認してソリューションに直接進むこともできます。
ローカル環境で最終結果を確認するには、次のいずれかを実行します。
このガイドのソースリポジトリをダウンロードして解凍します
Git を使用してリポジトリをクローンする:
git clone https://github.com/spring-guides/gs-accessing-data-mysql.git
リポジトリをフォークして、プルリクエストを送信することでこのガイドの変更をリクエストできるようにします。
MySQL データベースの設定
アプリケーションをビルドする前に、まず MySQL データベースを構成する必要があります。このガイドでは、Spring Boot Docker Compose サポートを使用することを前提としています。このアプローチの前提条件は、開発マシンに Docker デスクトップ (英語) などの Docker 環境が利用可能であることです。次の操作を実行する依存関係 spring-boot-docker-compose
を追加します。
作業ディレクトリで
compose.yml
やその他の一般的な compose ファイル名を検索します検出された
compose.yml
を使用してdocker compose up
を呼び出しますサポートされているコンテナーごとにサービス接続 Bean を作成する
アプリケーションのシャットダウン時に
docker compose stop
を呼び出します
Docker Compose サポートを使用するには、このガイドに従うだけです。取り込んだ依存関係に基づいて、Spring Boot は正しい compose.yml
ファイルを見つけ、アプリケーションの実行時に Docker コンテナーを起動します。
Spring Initializr から開始
IDE を使用する場合はプロジェクト作成ウィザードを使用します。IDE を使用せずにコマンドラインなどで開発する場合は、この事前に初期化されたプロジェクトからプロジェクトを ZIP ファイルとしてダウンロードできます。このプロジェクトは、このチュートリアルの例に合うように構成されています。
プロジェクトを手動で初期化するには:
IDE のメニューまたはブラウザーから Spring Initializr を開きます。アプリケーションに必要なすべての依存関係を取り込み、ほとんどのセットアップを行います。
Gradle または Maven のいずれかと、使用する言語を選択します。このガイドは、Java を選択したことを前提としています。
依存関係をクリックし、Spring Web、Spring Data JPA、MySQL ドライバー、Docker Compose サポート、Testcontainers を選択します。
生成をクリックします。
結果の ZIP ファイルをダウンロードします。これは、選択して構成された Web アプリケーションのアーカイブです。
@Entity
モデルを作成する
次のリスト(src/main/java/com/example/accessingdatamysql/User.java
)に示すように、エンティティモデルを作成する必要があります。
Hibernate は、エンティティを自動的にテーブルに変換します。
リポジトリを作成する
次のリスト(src/main/java/com/example/accessingdatamysql/UserRepository.java
)に示すように、ユーザーレコードを保持するリポジトリを作成する必要があります。
package com.example.accessingdatamysql;
import org.springframework.data.repository.CrudRepository;
import com.example.accessingdatamysql.User;
// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface UserRepository extends CrudRepository<User, Integer> {
}
Spring は、同じリポジトリの Bean にこのリポジトリインターフェースを自動的に実装します(ケースに変更があります。userRepository
と呼ばれます)。
コントローラーの作成
次のリスト(src/main/java/com/example/accessingdatamysql/MainController.java
)に示すように、アプリケーションへの HTTP リクエストを処理するコントローラーを作成する必要があります。
package com.example.accessingdatamysql;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller // This means that this class is a Controller
@RequestMapping(path="/demo") // This means URL's start with /demo (after Application path)
public class MainController {
@Autowired // This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
private UserRepository userRepository;
@PostMapping(path="/add") // Map ONLY POST Requests
public @ResponseBody String addNewUser (@RequestParam String name
, @RequestParam String email) {
// @ResponseBody means the returned String is the response, not a view name
// @RequestParam means it is a parameter from the GET or POST request
User n = new User();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
@GetMapping(path="/all")
public @ResponseBody Iterable<User> getAllUsers() {
// This returns a JSON or XML with the users
return userRepository.findAll();
}
}
上記の例では、2 つのエンドポイントに POST と GET を明示的に指定しています。デフォルトでは、@RequestMapping はすべての HTTP 操作をマップします。 |
アプリケーションクラスを作成する
Spring Initializr は、アプリケーションの単純なクラスを作成します。次のリストは、Initializr がこの例(src/main/java/com/example/accessingdatamysql/AccessingDataMysqlApplication.java
内)で作成したクラスを示しています。
package com.example.accessingdatamysql;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AccessingDataMysqlApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingDataMysqlApplication.class, args);
}
}
この例では、AccessingDataMysqlApplication
クラスを変更する必要はありません。
Spring Initializr は、メインクラスに @SpringBootApplication
アノテーションを追加します。@SpringBootApplication
は、次のすべてを追加する便利なアノテーションです。
@Configuration
: アプリケーションコンテキストの Bean 定義のソースとしてクラスにタグを付けます。@EnableAutoConfiguration
: Spring Boot は、追加した依存関係に基づいて、Spring アプリケーションを自動的に構成しようとします。@ComponentScan
: Spring に他のコンポーネント、構成、サービスを検索するように指示します。特定のパッケージが定義されていない場合は、アノテーションを宣言するクラスのパッケージから再帰スキャンが開始されます。
アプリケーションの実行
この時点で、アプリケーションを実行して、コードの動作を確認できます。メインメソッドは、IDE またはコマンドラインから実行できます。ソリューションリポジトリからプロジェクトをクローンした場合、IDE が compose.yaml
ファイルを間違った場所で探す可能性があることに注意してください。IDE を構成して正しい場所を探すか、コマンドラインを使用してアプリケーションを実行できます。./gradlew bootRun
コマンドと ./mvnw spring-boot:run
コマンドは、アプリケーションを起動し、compose.yaml ファイルを自動的に見つけます。
アプリケーションをテストする
アプリケーションが実行されたため、curl
または同様のツールを使用してテストできます。テストできる 2 つの HTTP エンドポイントがあります。
GET localhost:8080/demo/all
: すべてのデータを取得します。POST localhost:8080/demo/add
: 1 人のユーザーをデータに追加します。
次の curl コマンドは、ユーザーを追加します。
$ curl http://localhost:8080/demo/add -d name=First -d [email protected] (英語)
返信は次のようになります。
Saved
次のコマンドは、すべてのユーザーを表示します。
$ curl http://localhost:8080/demo/all
返信は次のようになります。
[{"id":1,"name":"First","email":"[email protected] (英語) "}]
アプリケーション構築の準備
アプリケーションをパッケージ化して実行するには、Spring Boot Docker Compose サポートを使用するのではなく、外部の MySQL データベースを提供する必要があります。このタスクでは、提供されている compose.yaml
ファイルをいくつかの変更を加えて再利用できます。まず、compose.yaml
の ports
エントリを 3306:3306
に変更します。次に、guide-mysql
の container_name
を追加します。
これらの手順を実行すると、compose.yaml
ファイルは次のようになります。
services:
mysql:
container_name: 'guide-mysql'
image: 'mysql:latest'
environment:
- 'MYSQL_DATABASE=mydatabase'
- 'MYSQL_PASSWORD=secret'
- 'MYSQL_ROOT_PASSWORD=verysecret'
- 'MYSQL_USER=myuser'
ports:
- '3306:3306'
これで、docker compose up
を実行してこの MySQL コンテナーを起動できます。
3 番目に、アプリケーションにデータベースへの接続方法を伝える必要があります。この手順は、以前は Spring Boot Docker Compose サポートによって自動的に処理されていました。これを行うには、application.properties
ファイルを次のように変更します。
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username=myuser
spring.datasource.password=secret
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql: true
アプリケーションの構築
このセクションでは、このガイドを実行するさまざまな方法について説明します。
アプリケーションの実行方法に関係なく、出力は同じになります。
アプリケーションを実行するには、アプリケーションを実行可能ファイル jar としてパッケージ化できます。./gradlew clean build
コマンドは、アプリケーションを実行可能ファイル jar にコンパイルします。その後、java -jar build/libs/accessing-data-mysql-0.0.1-SNAPSHOT.jar
コマンドを使用して jar を実行できます。
あるいは、Docker 環境が利用可能な場合は、buildpacks を使用して、Maven または Gradle プラグインから直接 Docker イメージを作成できます。Cloud Native Buildpacks を使用すると、どこでも実行できる Docker 互換イメージを作成できます。Spring Boot には、Maven と Gradle の両方に対する buildpack のサポートが直接含まれています。つまり、コマンドを 1 つ入力するだけで、ローカルで実行されている Docker デーモンに適切なイメージをすばやく取り込むことができます。Cloud Native Buildpacks を使用して Docker イメージを作成するには、./gradlew bootBuildImage
コマンドを実行します。Docker 環境が有効になっている場合は、docker run --network container:guide-mysql docker.io/library/accessing-data-mysql:0.0.1-SNAPSHOT
コマンドを使用してアプリケーションを実行できます。
--network フラグは、外部コンテナーが使用している既存のネットワークにガイドコンテナーを接続するように Docker に指示します。詳細については、Docker ドキュメント (英語) を参照してください。 |
ネイティブイメージのサポート
Spring Boot は、マシンに GraalVM ディストリビューションがインストールされている場合、ネイティブイメージへのコンパイルもサポートします。ネイティブビルドツールを使用して Gradle でネイティブイメージを作成するには、まず、Gradle ビルドに org.graalvm.buildtools.native
を含む plugins
ブロックが含まれていることを確認します。
plugins { id 'org.graalvm.buildtools.native' version '0.9.28' ...
次に、./gradlew nativeCompile
コマンドを実行してネイティブイメージを生成します。ビルドが完了したら、build/native/nativeCompile/accessing-data-mysql
コマンドを実行することで、ほぼ瞬時に起動してコードを実行できるようになります。
Buildpacks を使用したネイティブイメージを作成することもできます。./gradlew bootBuildImage
コマンドを実行してネイティブイメージを生成できます。ビルドが完了したら、docker run --network container:guide-mysql docker.io/library/accessing-data-mysql:0.0.1-SNAPSHOT
コマンドを使用してアプリケーションを起動できます。
Docker でアプリケーションをテストする
上記の Docker 命令を使用してアプリケーションを実行した場合、ターミナルまたはコマンドラインからの単純な curl コマンドは機能しなくなります。これは、ターミナルまたはコマンドラインからアクセスできない Docker ネットワーク (英語) でコンテナーを実行しているためです。curl コマンドを実行するには、3 番目のコンテナーを起動して curl コマンドを実行し、同じネットワークに接続します。
まず、MySQL データベースおよびアプリケーションと同じネットワーク上で実行されている新しいコンテナーへの対話型シェルを取得します。
docker run --rm --network container:guide-mysql -it alpine
次に、コンテナー内のシェルから curl をインストールします。
apk add curl
最後に、アプリケーションをテストするに従って、curl コマンドを実行できます。
セキュリティを変更する
本番環境では、SQL インジェクション攻撃にさらされる可能性があります。ハッカーは DROP TABLE
またはその他の破棄的な SQL コマンドを挿入する可能性があります。セキュリティ対策として、アプリケーションをユーザーに公開する前に、データベースにいくつかの変更を加える必要があります。
次のコマンドは、Spring アプリケーションに関連付けられているユーザーからすべての特権を取り消します。
mysql> revoke all on db_example.* from 'myuser'@'%';
これで、Spring アプリケーションはデータベースで何もできなくなりました。
アプリケーションには何らかの特権が必要であるため、次のコマンドを使用して、アプリケーションに必要な最小限の特権を付与します。
mysql> grant select, insert, delete, update on db_example.* to 'myuser'@'%';
すべての特権を削除して一部の特権を付与すると、Spring アプリケーションに、構造(スキーマ)ではなくデータベースのデータのみを変更するために必要な特権が付与されます。
データベースに変更を加える場合:
許可を再付与します。
spring.jpa.hibernate.ddl-auto
をupdate
に変更します。アプリケーションを再実行します。
次に、ここに示す 2 つのコマンドを繰り返して、アプリケーションを再び本番環境で安全に使用できるようにします。さらに良い方法は、Flyway や Liquibase などの専用の移行ツールを使用することです。
要約
おめでとう! MySQL データベースにバインドされた Spring アプリケーションを開発し、本番の準備ができました!
関連事項
次のガイドも役立ちます。
新しいガイドを作成したり、既存のガイドに貢献したいですか? 投稿ガイドラインを参照してください [GitHub] (英語) 。
すべてのガイドは、コード用の ASLv2 ライセンス、およびドキュメント用の Attribution、NoDerivatives creative commons ライセンス (英語) でリリースされています。 |