💾 Spring Framework 講座【第20回】DB連携の主役!〜データ永続化の基本とJPA/Hibernate〜

docs

前回、Spring Bootのプロファイル機能を使って、環境ごとに設定を切り替える方法を学びました。これでアプリケーションの**「設定」**も万全です。

今回からは、業務システムの根幹であり、最も複雑な領域であるデータベース連携に進みます。Javaでデータベース操作を行う標準的な仕組みである JPA (Java Persistence API) と、その実装である Hibernate (ハイバネート) について、基本概念を理解しましょう。

1. データ永続化とは?

**データ永続化(Persistence)**とは、プログラムの実行が終了したり、電源が切れたりしても、データが失われずに存在し続けるようにすることです。

Webアプリケーションにおいて、この永続化の役割を担うのが**データベース(DB)**です。

JavaプログラムからDBを操作するには、直接 SQL 文(Structured Query Language)を書く方法もありますが、以下の問題があります。

  1. DB依存性: DBの種類(MySQL、PostgreSQLなど)が変わると、SQL文を書き直す必要がある。
  2. オブジェクトとリレーショナルの不一致: Javaはオブジェクト指向ですが、DBはテーブル構造を持つリレーショナルな仕組みです。この構造の違いを変換する手間(インピーダンスミスマッチ)が大きい。

この問題を解決するのが O/Rマッピングの技術です。

2. O/RマッピングとJPA

O/Rマッピング(Object-Relational Mapping)とは、Javaのオブジェクト(クラスやインスタンス)と、リレーショナルデータベースのテーブルレコードを対応付け(マッピング)させる技術です。

このO/Rマッピングを実現するための**「仕様(ルール)」**が JPA (Java Persistence API) です。

  • JPA: DB操作のルールを定めたJavaの標準仕様(インターフェース)。「DBからデータを取ってくるときは、このメソッドを使いなさい」という契約
  • Hibernate: JPAという仕様に沿って、実際にDB操作を実行する実装ライブラリ(エンジン)。

Spring Bootでは、JPAというインターフェースを使い、その裏側でHibernateを動かすのが標準的なDB連携方法です。


3. Entity(エンティティ)の定義:Javaクラスとテーブルの対応

JPAにおいて、DBのテーブルに対応するJavaのクラスを **Entity(エンティティ)**と呼びます。

Entityクラスを定義することで、プログラマはSQL文を直接書かずに、Javaのオブジェクト操作を通じてDBを操作できるようになります。

3-1. Entityクラスの基本構造

Entityとして扱うクラスには、主に3つのアノテーションを付与します。

  1. @Entity: このクラスがDBのテーブルに対応する永続化オブジェクトであることを示す。
  2. @Table: 実際にマッピングされるDBのテーブル名を指定する(クラス名とテーブル名が同じ場合は省略可)。
  3. @Id: そのテーブルの**主キー(Primary Key)**となるフィールドを指定する。

Java

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity // 永続化オブジェクトとして定義
@Table(name = "items") // DBの items テーブルに対応
@Data // Lombokによるgetter/setter自動生成
@NoArgsConstructor // 引数なしコンストラクタの自動生成 (JPAで必須)
public class Item {
    
    @Id // 主キーとして設定
    private Long id;
    
    // フィールド名とカラム名が同じであれば、特別なアノテーションは不要
    private String name;
    
    private int price;
    
    // ... その他のフィールド
}

3-2. 主キーの自動生成

主キーの値をDB側で自動的に生成させたい場合は、@GeneratedValue アノテーションを追加します。

Java

import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
// ... (他のimport)

public class Item {
    
    @Id
    // DB側で自動採番されるように設定(IDENTITYはMySQLなどで一般的)
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id;
    
    // ...
}

4. Repositoryの再定義(JPA利用)

前回まで、Repository層では「架空のDB操作」を行っていましたが、JPAを使うとRepositoryの定義方法が変わります。

JPAを使うRepositoryは、Spring Data JPAという機能を通じて、インターフェースとして定義するだけで、基本的なDB操作メソッド(保存、検索など)をSpringが自動で実装してくれます

Java

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

// ItemRepository.java
// JpaRepositoryインターフェースを継承するだけでOK
// <Entityクラス, 主キーの型> を指定する
@Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
    
    // このインターフェースを定義するだけで、以下のメソッドが使えるようになる
    // save(Item item)
    // findById(Long id)
    // findAll()
    // delete(Item item)
}

【驚きポイント】 ItemRepositoryインターフェースですが、Springコンテナは実行時に、このインターフェースを実装した実体(Bean)を自動で生成し、ControllerやService層に注入できるようにします。これがSpring Data JPAの強力さです。

✅ 本日のまとめ

  • データ永続化は、プログラム終了後もデータを保持する仕組みで、DBが担う。
  • JPA はO/Rマッピングのための標準仕様であり、Hibernateはその実装の一つ。
  • DBのテーブルに対応するJavaクラスを Entity と呼び、@Entity@Id@Table で定義する。
  • @GeneratedValue で主キーの自動生成を設定できる。
  • Spring Data JPA を使うと、JpaRepository<Entity, 主キー型> を継承したインターフェースを定義するだけで、基本的なDB操作メソッドを持ったBeanが自動生成される。

🔔 次回予告

今回、JPAの基本構造とRepositoryの定義を学びましたが、この自動生成されたRepositoryでは対応できない、より複雑な検索処理が必要になることがほとんどです。

次回は、Spring Data JPAで、自動生成されたメソッド以外に、自分でカスタムの検索メソッド(例: 名前で検索、価格帯で検索)を簡単に追加する方法について学びます。

次回:【第21回】Spring Data JPA (1) – 基本的なCRUD操作とカスタム検索 にご期待ください!

コメント

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