Spring Bootでのデータベース連携入門

Java

はじめに

Spring BootでWebアプリケーションを作成する際、データベース連携は欠かせない重要な部分です。今回は、Spring Data JPAを使用してデータベースを操作する方法と、MySQLなど外部データベースとの接続設定について解説します。この記事では、初心者向けに、基礎からデータベース連携の流れを学びます。

Spring Data JPAの概要

Spring Data JPA は、データベース操作を簡素化するための強力なライブラリです。複雑なSQLを記述せず、Javaのオブジェクト(エンティティ)を使ってデータベース操作を行えるようにしてくれます。特に、CRUD(作成、読み取り、更新、削除)の操作を自動的に処理する仕組みが特徴です。

Spring Data JPAの利点

  1. コードの簡潔化:
    • SQLを書く手間がほぼ不要。
    • リポジトリのメソッド名だけでクエリを生成可能。
  2. 再利用性の向上:
    • リポジトリを複数のサービスやコントローラーで再利用できる。
  3. データアクセス層の標準化:
    • データベース操作のロジックが統一される。
  4. 柔軟なクエリ作成:
    • 宣言的クエリやカスタムクエリを簡単に利用可能。

注意点と課題

  1. 自動生成されるSQLに注意:
    • 自動生成されたSQLが期待通りでない場合があります。ログを確認して最適化が必要になることも。
  2. 大規模データの処理:
    • データ量が多い場合、パフォーマンスチューニングが必要(例: ページングやソートを適切に使う)。
  3. 柔軟性の限界:
    • 非標準的なクエリや複雑なロジックでは、ネイティブSQLやカスタムクエリが必要になる場合があります。

環境の準備

環境構築を行なっていきます。
必要な項目は下記です。

  • MySQLの準備
  • Spring Bootプロジェクトの作成

MySQLの準備

MySQLのインストール

今回はAppleシリコンのMacの場合を想定して環境構築していきます。

Homebrewを利用してインストールします。

Bash
brew install mysql

インストールが完了したら、MySQLを起動します。

Bash
brew services start mysql

正常に動作しているか確認するため、以下のコマンドでMySQLに接続します。
(初回接続の場合、パスワードは設定されていないため、直接接続できます)

Bash
mysql -u root

初期設定

MySQLのrootユーザーのパスワードを設定し、必要なデータベースを作成します。

MySQLにログインした状態で、rootユーザーのパスワードを設定します。
your_password には任意のパスワードを設定します。

SQL
ALTER USER 'root'@'localhost' IDENTIFIED BY 'your_password'; 

Spring Bootで使用するデータベースを作成します。以下のコマンドを実行してください。

SQL
CREATE DATABASE springbootdb;

MySQLからログアウトします。

SQL
exit;

起動・停止コマンド

MySQLを手動で起動・停止したい場合は、以下のコマンドを使用できます。

Bash
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データベースと接続します。

Bash
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 にエンティティクラスを作成します。

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 にリポジトリインターフェースを作成します。

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 にサービスクラスを作成します。

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 にコントローラーを作成します。

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)

すべてのユーザーを取得するために、以下のコマンドを使用します。

Bash
curl -X GET http://localhost:8080/api/users

特定のユーザーをIDで取得 (GET)

例えば、IDが1のユーザーを取得するには、以下のようにします。

Bash
curl -X GET http://localhost:8080/api/users/1

新しいユーザーを作成 (POST)

ユーザーを新規作成するために、-X POST を使用して、ユーザーデータをJSONフォーマットで送信します。

Bash
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 を使用して更新データを送信します。

Bash
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 を使用します。

Bash
curl -X DELETE http://localhost:8080/api/users/1

まとめ

各ファイルの役割をまとめると下記になります。

全体の流れ

  1. クライアント(ブラウザやAPIクライアント)がリクエストを送信します。
  2. コントローラーがリクエストを受け取り、サービスクラスに処理を依頼します。
  3. サービスクラスがリポジトリを使ってデータベースにアクセスし、必要な処理を行います。
  4. コントローラーが結果をクライアントに返します。

役割を整理した例え

  • エンティティクラス: データそのもの(例えば「ユーザー」というカード)
  • リポジトリインターフェース: データの出し入れを担当する「倉庫」
  • サービスクラス: 倉庫で取り出したデータを加工する「調理師」
  • コントローラー: クライアントからのリクエストを受け取り、調理師に指示する「ウェイター」

ここまでで、Spring Bootを使ってデータベースと連携し、簡単なCRUD操作を行う方法を学びました。Spring Data JPAの強力な機能により、複雑なSQLを書かずにデータ操作が可能となります。データベース連携の基本を理解することで、さらに多機能なアプリケーション開発ができるようになるでしょう。

コメント

タイトルとURLをコピーしました