H2入門の第2回です。H2データベースの接続設定(application.properties)、Spring Data JPAのエンティティクラスの作成、またDBの初期データの作成をやっていきます。Spring Bootの初心者・入門者の方は、参考にしてみてください。
※ 本ページはプロモーションが含まれています。
前回は、H2データベースを試すためのSpring Bootのプロジェクト作成までをやりました。
(第1回) 手軽に試せるH2データベース入門【H2, Spring Boot2】
今回は、H2の接続設定やJavaのエンティティクラスの作成、またDBの初期データの作成をやっていきます。
・動作環境やバージョンは以下の通りです。
OS:macOS Big Sur(バージョン11.7.1)
開発環境:Eclipse(Pleiades All in One、4.16(2020-06)、Java Full Edition版)
Spring Boot:バージョン2.7.6
Java:11
前回test-h2というSpring Bootのプロジェクトを作成しましたが、今回作成するファイルを先に書いておきます。
作成するファイルは3つです。
まずは、application.propertiesファイルでH2接続設定をします。application.propertiesファイルは、Spring Bootプロジェクト作成時に以下のパスに自動で作られます。
src/main/resource/application.properties
application.propertiesファイルを編集します。ユーザ名とパスワードはコメントアウトしているので、設定しているのは"spring.datasource.driver-class-name"、"spring.datasource.url"プロパティの2箇所です。
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:hogedb
#とりあえず自分でテスト的にH2を試すだけなので、DBのユーザ名とパスワードはコメントアウトして未設定にしておく
#spring.datasource.username=hogeuser
#spring.datasource.password=pass
"spring.datasource.driver-class-name"プロパティは、"spring.datasource.driverClassName"でも良いです。
spring.datasource.driverClassName=org.h2.Driver
H2のデータの保存先はメモリだけでなく、ファイルに保存する事もできます。ファイル保存だとデータを永続的に残せるので、アプリを終了してもデータは残ります。
H2をファイルベースで利用する時の方法や設定については別ページ(第8回)で説明していますので、そちらを参考にしてください。
(第8回)H2のデータをファイルに保存、データの永続化【Spring Boot2】
次に、Spring Data JPAのエンティティクラスを作成します。今回は、日記、もしくはメモ帳やツイートなどのデータを想定して、単純なDiaryクラスを作成します。
src/main/java配下のcom.example.demoパッケージ下にDiary.javaファイルを作成して編集します。
package com.example.demo;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
//@Table(name = "diaries") //指定しないとテーブルはクラス名と同じdiary
public class Diary {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String comment;
@Column(name = "create_datetime", nullable = false)
private LocalDateTime createDatetime;
}
エンティティクラスのフィールドは3つだけです。
まず、Spring Data JPAのエンティティクラスである事を表すために、クラス名に@Entityを付けます。
@Tableはコメントアウトしていますが、エンティティクラス名とH2データベースのテーブル名が異なる場合、@Tableのnameでテーブル名を指定して、エンティティクラスとテーブル名をマッピングします。
上のコードでは@Tableは指定していませんので、アプリ起動時にエンティティクラスと同じ名前のDiaryというテーブルが、Spring Data JPAによって自動生成されます。
フィールドのidに付与している@Idは、エンティティの主キーという事です。
@GeneratedValueは主キーが自動採番される事、strategy=GenerationType.IDENTITYは採番方法を示しています。
フィールドのcreateDatetimeに付与している@Columnは、テーブルのフィールドに対する設定をしています。「name = "create_datetime"」はテーブルにあるフィールド名を"create_datetime"に設定し、「nullable = false」はフィールドの値をnull禁止(not null)にしています。
@Columnを付与しないと、エンティティのフィールド名とテーブルのフィールド名は同じになります。
@Data、@NoArgsConstructor、@AllArgsConstructorは全て、Lombokのアノテーションです。これらを付ける事で、フィールドのセッター・ゲッター、クラスのコンストラクタのコードが自動生成されるので、エンティティクラスのコード量を削減できます。
Eclipseの場合、アウトラインビューでクラスにあるフィールド、メソッド、コンストラクタの一覧が見れますので、ここでLombokによって自動生成されたメソッドなども確認できます。
次に、初期データを作成するためのDML(Data Manipulation Language)ファイルの作成です。
Spring Bootでは、プロジェクトのsrc/main/resourcesディレクトリ下にdata.sqlファイルを作成し、このファイルにDMLのInsert SQLを書いておくと、Spring Bootアプリ起動時に自動でdata.sqlをロードしてSQLを実行して初期データを作ってくれます。
実際にdata.sqlファイルを作成して編集します。
(*data.sqlに書くsqlをコメントアウトしたい場合は、行頭に"--"を付けます)
INSERT INTO diary(comment, create_datetime) VALUES('今日は晴れ。コメント1', LOCALTIME());
INSERT INTO diary(comment, create_datetime) VALUES('comment 2', LOCALTIME());
INSERT INTO diary(comment, create_datetime) VALUES('こめんと3', LOCALTIME());
上で作成したエンティティクラスのDiaryに合わせてsqlを作成しました。テスト的に3レコード分追加するsqlです。また、application.propertiesファイルにspring.jpa.defer-datasource-initializationプロパティの設定を1行追加します。
spring.jpa.defer-datasource-initialization=true
spring.jpa.defer-datasource-initializationプロパティは、Spring Bootのバージョン2.5以上に必要な設定なので、バージョン2.4以下なら書く必要は無いです。
これは、Spring Bootの2.4から2.5へのバージョンアップ時にdata.sqlとschema.sql周りのデータ初期化スクリプトの仕様変更があり、2.4系まではエンティティクラスがある場合、エンティティクラスからDBのテーブルが生成された後に、data.sqlにあるInsert SQLが実行される流れだったのが、2.5系にバージョンアップされてからはその順序が逆になり、先にdata.sqlがロードされてにSQLが実行され、その後にエンティティクラスからDBのテーブルが生成されるようになりました。
ですので、バージョン2.5以上ではDBテーブルが無い状態でdata.sqlにあるInsert SQLが実行されてエラーが発生するのですが、上記の「spring.jpa.defer-datasource-initialization=true」を追記すれば、順序をエンティティクラスがテーブルを生成して、その後にdata.sqlを実行する事ができます。
この問題については別ページでもう少し詳しく説明しているので、よければ参考にしてください。
Spring Boot2.4から2.7へバージョンアップ時にエラー発生
◾️DDL(Data Definition Language)のschema.sql
Spring Bootでは、DMLのdata.sqlだけでなく、DDLのschema.sqlファイルをsrc/main/resourcesディレクトリ下に作成すれば、アプリ起動時にdata.sqlと同じく自動でschema.sqlをロードして実行してくれます。
そうすれば、schema.sqlでDBのテーブルを作成して、data.sqlでDBデータを初期化できるので、Diaryエンティティクラスでテーブル生成する必要がなくなりますし、この方法であれば、Spring Bootのバージョン2.5以上でも"spring.jpa.defer-datasource-initialization"プロパティを設定する必要がありません。
schema.sqlを使う方法は第7回の記事で説明しているので、よければそちらを参考にしてください。
(第7回) schema.sqlを使用してDBのテーブル作成【H2, Spring Boot2】
以上今回は、H2への接続設定、エンティティクラスDiaryの作成、DMLのdata.sqlを作成しました。
これでアプリを実行すれば、H2のDBがインメモリで生成され、エンティティクラスDiaryからSpring Data JPAによってdiaryテーブルが自動生成され、data.sqlで書いた3レコード分のデータが生成されます。
次回は、Spring Bootアプリの起動によって生成されるH2DBのテーブルやデータは、H2の管理ツールの"H2 Console"で確認する事ができますので、H2 Consoleの使い方について書いていきます。
(第3回) H2のブラウザ管理ツール"H2 Console"の使い方【H2, Spring Boot2】
H2データベース入門【Spring Boot】トップに戻る
Spring Boot2で日記投稿ウェブアプリ開発入門トップページ
Spring Bootでシンプルな日記投稿ウェブアプリの開発しながら、入門者・初心者にもわかりやすいように説明しています。DBを使用して、新規投稿、編集、削除、一覧表示という基本的なCRUD機能を備えたアプリです。