こんにちは、かつコーチです。
Spring Bootでデータベースを扱うとき、多くの現場で使われているのがSpring Data JPAです。
「JDBCと何が違うの?」「Entityって結局なに?」というところで止まってしまう人が多いので、今回は基本の考え方とEntityの定義方法を整理していきます。
Spring Data JPAとは
JPAとHibernateの関係
JPA(Java Persistence Association)とは、Javaのオブジェクトとデータベースのテーブルを結びつけるための標準仕様です。
JPA自体は「こういうルールで実装してね」という仕様書のようなもので、実際に処理を行う実装が必要になります。
その実装の代表格がHibernateというライブラリで、Spring Bootでは特に設定しなくてもHibernateが標準で使われます。
Spring Data JPAは、このJPAをさらに使いやすくラップしたSpringのモジュールで、SQLをほとんど書かずにデータベース操作ができるようになります。
なぜSQLを直接書かないのか
JDBCで直接SQLを書く方法もありますが、テーブルの列が増えるたびにSQL文とマッピング処理を手作業で修正する必要があり、ミスが起きやすくなります。
Spring Data JPAでは、Javaのクラス(Entity)とテーブルの対応関係を一度定義しておけば、あとはJavaのメソッド呼び出しだけでデータの読み書きができます。
ORM(Object-Relational Mapping)と呼ばれる、オブジェクトとリレーショナルデータベースを対応付ける仕組みの一種です。
Entityの定義方法
依存関係の追加
まずbuild.gradle(またはpom.xml)にSpring Data JPAとデータベースドライバを追加します。
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
}
基本のEntityクラス
Entityは、データベースのテーブル1つに対応するJavaクラスです。
package com.example.demo.entity;
import jakarta.persistence.*;
@Entity
@Table(name = "books")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 100)
private String title;
@Column(name = "author_name")
private String author;
private int price;
// getter/setterは省略
}
@Entity:このクラスがJPAの管理対象であることを示す@Table(name = "books"):対応するテーブル名を指定(省略時はクラス名がそのまま使われる)@Id:主キーに対応するフィールドを指定@GeneratedValue:主キーの採番方法を指定(IDENTITYはDB側のAUTO_INCREMENTに任せる方式)@Column:カラムの詳細設定(省略した場合はフィールド名がそのままカラム名になる)
Spring Boot 3.x系ではjavax.persistenceではなくjakarta.persistenceパッケージを使う点に注意してください。
Spring Boot 2系の記事や書籍を参考にするとjavax.persistenceのままインポートしてしまい、依存関係が解決できずにビルドエラーになることがあります。
つまずきやすいポイント
デフォルトコンストラクタの省略
❌ Before:引数ありコンストラクタしか定義しない
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
public Book(String title) {
this.title = title;
}
}
これを実行すると、Hibernateがデータを取得する際にInstantiationExceptionが発生します。
Hibernateは内部でリフレクションを使い、引数なしのコンストラクタでインスタンスを生成してからフィールドに値を詰めるためです。
✅ After:引数なしコンストラクタを明示的に用意する
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
protected Book() {}
public Book(String title) {
this.title = title;
}
}
Lombokの@NoArgsConstructorを使えば、この定型コードを1行で済ませることもできます。
応用・一歩先の使い方
テーブル自動生成の設定
application.propertiesに以下を設定すると、起動時にEntityの定義からテーブルを自動生成してくれます。
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
ddl-auto=updateは開発中は便利ですが、本番環境で使うと意図しないテーブル変更が起きるリスクがあるため、本番ではvalidateやnoneに切り替えるのが定石です。
まとめ
この記事のポイント
- JPAはオブジェクトとテーブルを結びつける標準仕様、Hibernateはその実装
@Entity・@Id・@ColumnでEntityとテーブルの対応関係を定義する- Spring Boot 3.x系では
jakarta.persistenceパッケージを使う - Entityには引数なしコンストラクタが必須
次に読むべき記事
- Repositoryインターフェースの基本
- CRUD操作の実装
- @OneToMany・@ManyToOneでリレーションを組む
タグ: Spring Boot, 初心者向け, データベース