はじめに
Spring BootでWebアプリケーションを作成する際、データベース連携は欠かせない重要な部分です。今回は、Spring Data JPAを使用してデータベースを操作する方法と、MySQLなど外部データベースとの接続設定について解説します。この記事では、初心者向けに、基礎からデータベース連携の流れを学びます。
Spring Data JPAの概要
Spring Data JPA は、データベース操作を簡素化するための強力なライブラリです。複雑なSQLを記述せず、Javaのオブジェクト(エンティティ)を使ってデータベース操作を行えるようにしてくれます。特に、CRUD(作成、読み取り、更新、削除)の操作を自動的に処理する仕組みが特徴です。
Spring Data JPAの利点
- コードの簡潔化:
- SQLを書く手間がほぼ不要。
- リポジトリのメソッド名だけでクエリを生成可能。
- 再利用性の向上:
- リポジトリを複数のサービスやコントローラーで再利用できる。
- データアクセス層の標準化:
- データベース操作のロジックが統一される。
- 柔軟なクエリ作成:
- 宣言的クエリやカスタムクエリを簡単に利用可能。
注意点と課題
- 自動生成されるSQLに注意:
- 自動生成されたSQLが期待通りでない場合があります。ログを確認して最適化が必要になることも。
- 大規模データの処理:
- データ量が多い場合、パフォーマンスチューニングが必要(例: ページングやソートを適切に使う)。
- 柔軟性の限界:
- 非標準的なクエリや複雑なロジックでは、ネイティブSQLやカスタムクエリが必要になる場合があります。
環境の準備
環境構築を行なっていきます。
必要な項目は下記です。
- MySQLの準備
- Spring Bootプロジェクトの作成
MySQLの準備
MySQLのインストール
今回はAppleシリコンのMacの場合を想定して環境構築していきます。
Homebrewを利用してインストールします。
brew install mysql
インストールが完了したら、MySQLを起動します。
brew services start mysql
正常に動作しているか確認するため、以下のコマンドでMySQLに接続します。
(初回接続の場合、パスワードは設定されていないため、直接接続できます)
mysql -u root
初期設定
MySQLのrootユーザーのパスワードを設定し、必要なデータベースを作成します。
MySQLにログインした状態で、rootユーザーのパスワードを設定します。
your_password には任意のパスワードを設定します。
ALTER USER 'root'@'localhost' IDENTIFIED BY 'your_password';
Spring Bootで使用するデータベースを作成します。以下のコマンドを実行してください。
CREATE DATABASE springbootdb;
MySQLからログアウトします。
exit;
起動・停止コマンド
MySQLを手動で起動・停止したい場合は、以下のコマンドを使用できます。
mysql.server start
mysql.server stop
Spring Bootプロジェクトの作成
Spring Initializrにアクセスします。
今回は下記設定で実施します。(他は初期設定です。)
- Project: Gradle Project
- Language: Java
- Spring Boot Version: 3.3.5
- Artifact: sql
- Dependencies :「Spring Web」「Spring Data JPA」「MySQL Driver」を追加
「Generate」をクリックしてプロジェクトをダウンロードし、解凍します。
実装
今回はUserTBを作成し、CRUD機能を実装していきます。
実装していく内容は下記です。
- データベースの接続設定
- エンティティクラス
- リポジトリインターフェース
- サービスクラス
- コントローラー
データベース設定
以下の内容を src/main/resources/application.properties
に記述し、MySQLデータベースと接続します。
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb
spring.datasource.username=root
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
※ your_password
はMySQLのパスワードに置き換えてください。
ポイント
spring.jpa.hibernate.ddl-auto=update
Spring BootとJPAでは、エンティティクラスを定義するだけで、JPAが自動的にデータベースのテーブルを作成してくれます。この自動生成は、application.properties
に以下の設定を記述することで制御できます。
ddl-autoのオプション
none
: テーブルの作成や更新を行わない。create
: アプリケーション起動時にテーブルを作成する(既存のデータは削除)。create-drop
: アプリケーション起動時にテーブルを作成し、終了時に削除。update
: テーブルを更新する(既存データは維持)。validate
: エンティティとテーブルの構造が一致しているかを検証する。
エンティティクラス User
概要
エンティティクラスとはデータベースの「テーブル」と「アプリケーション内のオブジェクト」を対応付ける役割を持つクラスです。
役割
データベースでは、情報を「テーブル」に保存しますが、Javaではデータを「オブジェクト」で扱います。この橋渡しをするのがエンティティクラスです。
例
src/main/java/com/example/sql/model/User.java
にエンティティクラスを作成します。
package com.example.sql.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
public User() {}
public User(String name, String email) {
this.name = name;
this.email = email;
}
public Long getId() { return id; }
public void setId(Long 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; }
}
ポイント:
@Entity
: このクラスがデータベースのテーブルに対応していることを示します。- クラスのフィールド(例:
id
,name
,email
)がテーブルの列に対応します。
リポジトリインターフェース UserRepository
概要
データベースにアクセスして、情報を保存、取得、更新、削除する機能を提供します。
役割
エンティティクラスを使って、「データベースから情報を取ってくる」「新しいデータを保存する」などを自動でやってくれる便利な機能です。
例
src/main/java/com/example/sql/repository/UserRepository.java
にリポジトリインターフェースを作成します。
package com.example.sql.repository;
import com.example.sql.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
ポイント
JpaRepository
: Spring Data JPAが提供するインターフェースで、データ操作(CRUD)を簡単に行えます。- メソッドを追加しなくても、以下の操作がすぐ使えます:
findAll()
: 全データを取得findById(id)
: 特定IDのデータを取得save(entity)
: データを保存または更新deleteById(id)
: 特定IDのデータを削除
サービスクラス UserService
概要
ビジネスロジック(処理の流れ)を実装する役割を持ちます。リポジトリとコントローラーの間でデータの加工や条件をチェックします。
役割
「データをどう扱うか」を決める役割です。たとえば、データをデータベースに保存する前に確認したり、複数のデータを加工して返したりします。
例
src/main/java/com/example/sql/service/UserService.java にサービスクラスを作成します。
package com.example.sql.service;
import com.example.sql.model.User;
import com.example.sql.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> getAllUsers() {
return userRepository.findAll();
}
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
public User createUser(User user) {
return userRepository.save(user);
}
public User updateUser(Long id, User userDetails) {
User user = getUserById(id);
if (user != null) {
user.setName(userDetails.getName());
user.setEmail(userDetails.getEmail());
return userRepository.save(user);
}
return null;
}
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
ポイント
- データベースへの操作はリポジトリを通じて行います。
- コントローラーで必要な処理を整理し、再利用できるようにします。
コントローラー UserController
概要
アプリケーションの「入り口」として、リクエスト(操作の要求)を受け取り、サービスに処理を依頼して、レスポンス(結果)を返します。
例
src/main/java/com/example/sql/controller/UserController.java
にコントローラーを作成します。
package com.example.sql.controller;
import com.example.sql.model.User;
import com.example.sql.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.getUserById(id);
return user == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(user);
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.createUser(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
User updatedUser = userService.updateUser(id, userDetails);
return updatedUser == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
}
ポイント
@RestController
: HTTPリクエストを処理するクラスであることを示します。- リクエストのURLやメソッドに応じてサービスクラスを呼び出します。
動作確認
cURLを使ってSpring BootアプリケーションのCRUDエンドポイントをテストします。
以下では、GET、POST、PUT、DELETEの各操作を行います。
全ユーザーを取得 (GET)
すべてのユーザーを取得するために、以下のコマンドを使用します。
curl -X GET http://localhost:8080/api/users
特定のユーザーをIDで取得 (GET)
例えば、IDが1のユーザーを取得するには、以下のようにします。
curl -X GET http://localhost:8080/api/users/1
新しいユーザーを作成 (POST)
ユーザーを新規作成するために、-X POST
を使用して、ユーザーデータをJSONフォーマットで送信します。
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name": "John Doe", "email": "john@example.com"}'
ユーザーを更新 (PUT)
例えば、IDが1のユーザーの情報を更新する場合は、-X PUT
を使用して更新データを送信します。
curl -X PUT http://localhost:8080/api/users/1 \
-H "Content-Type: application/json" \
-d '{"name": "John Doe Updated", "email": "john.updated@example.com"}'
ユーザーを削除 (DELETE)
例えば、IDが1のユーザーを削除するには、-X DELETE
を使用します。
curl -X DELETE http://localhost:8080/api/users/1
まとめ
各ファイルの役割をまとめると下記になります。
全体の流れ
- クライアント(ブラウザやAPIクライアント)がリクエストを送信します。
- コントローラーがリクエストを受け取り、サービスクラスに処理を依頼します。
- サービスクラスがリポジトリを使ってデータベースにアクセスし、必要な処理を行います。
- コントローラーが結果をクライアントに返します。
役割を整理した例え
- エンティティクラス: データそのもの(例えば「ユーザー」というカード)
- リポジトリインターフェース: データの出し入れを担当する「倉庫」
- サービスクラス: 倉庫で取り出したデータを加工する「調理師」
- コントローラー: クライアントからのリクエストを受け取り、調理師に指示する「ウェイター」
ここまでで、Spring Bootを使ってデータベースと連携し、簡単なCRUD操作を行う方法を学びました。Spring Data JPAの強力な機能により、複雑なSQLを書かずにデータ操作が可能となります。データベース連携の基本を理解することで、さらに多機能なアプリケーション開発ができるようになるでしょう。
コメント