前回、Spring Bootのプロファイル機能を使って、環境ごとに設定を切り替える方法を学びました。これでアプリケーションの**「設定」**も万全です。
今回からは、業務システムの根幹であり、最も複雑な領域であるデータベース連携に進みます。Javaでデータベース操作を行う標準的な仕組みである JPA (Java Persistence API) と、その実装である Hibernate (ハイバネート) について、基本概念を理解しましょう。
1. データ永続化とは?
**データ永続化(Persistence)**とは、プログラムの実行が終了したり、電源が切れたりしても、データが失われずに存在し続けるようにすることです。
Webアプリケーションにおいて、この永続化の役割を担うのが**データベース(DB)**です。
JavaプログラムからDBを操作するには、直接 SQL 文(Structured Query Language)を書く方法もありますが、以下の問題があります。
- DB依存性: DBの種類(MySQL、PostgreSQLなど)が変わると、SQL文を書き直す必要がある。
- オブジェクトとリレーショナルの不一致: 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つのアノテーションを付与します。
@Entity: このクラスがDBのテーブルに対応する永続化オブジェクトであることを示す。@Table: 実際にマッピングされるDBのテーブル名を指定する(クラス名とテーブル名が同じ場合は省略可)。@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操作とカスタム検索 にご期待ください!


コメント