概要
データアクセスフレームワークであるSpring JDBCを使用して、H2DBにアクセスする方法についてまとめた。
当記事ではSpring JDBCの特徴と、H2DBにアクセスするための準備方法について紹介する。
Spring JDBC
Spring JDBCは、JavaのJDBC APIを使いやすくするためにSpring Frameworkが提供している機能となる。
JDBCの煩雑な処理を隠蔽して、シンプルな記述でDBアクセスを行うことができる。
Javaの標準APIであるJDBCを使用すると、下記のような煩雑な処理を実装する必要がある。
・エラー処理(検査例外のSQLExceptionがスローされるため、try-catchが必要)
・処理結果行のループ処理
Spring JDBCでは、上記のような煩雑な処理を実装する必要がなく、下記のように簡素な実装になる。
・結果のマッピング
簡素な処理を記述するため、Spring JDBCでは「JdbcTemplate」または「NamedParameterJdbcTemplate」クラスが用意されている。
尚、上記のクラスを使用するためにはDIコンテナに登録しておく必要がある。
概要 Spring MVCでは「データソース」と「データアクセスフレームワーク」を使用してDBアクセスを行う。 今回はそれぞれの概念について簡単にまとめた。 また、「データアクセスフレームワーク」を使用しない場合についてもあわせて[…]
JdbcTemplate
JdbcTemplateはJDBCの中心機能をラップして簡素化したAPIを提供する。
これにより、開発者はJDBCの煩雑さを気にすることなくDB操作ができる。
NamedParameterJdbcTemplate
JdbcTemplateの機能を拡張して、バインド変数に名前付きパラメータを指定できる。
これによりJdbcTemplateより、わかりやすくSQL文を管理できる。
DIコンテナに登録
Spring JDBCの「JdbcTemplate」または「NamedParameterJdbcTemplate」は以下のようにDIコンテナに登録して使用することが推奨されている。
applicationContext.xml
<!-- JdbcTemplateを使用する場合 -->
<bean class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
<!-- NamedParameterJdbcTemplateを使用する場合 -->
<bean
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
JdbcTemplateまたはNamedParameterJdbcTemplateをBean登録する際、dataSourceオブジェクトをインジェクションしている。
dataSourceは後述するH2のデータソースを参照している。
必要なモジュールの追加
Spring JDBCが提供するTemplateクラスを使用するため、pom.xmlにモジュールの依存関係を追加する。
pom.xml
<!-- Spring JDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.20.RELEASE</version><!-- spring-webmvcのバージョンに合わせる -->
</dependency>
H2DBのデータソースの登録
H2DBのデータソースを使用するため、DIコンテナに登録する。
DIコンテナに登録
以下はH2のtestdbというデータベースに接続するデータソースを作成している。
applicationContext.xml
<!-- H2 DBのデータソース -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url"
value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" />
</bean>
必要なモジュールの追加
H2DBを使用するため、pom.xmlにモジュールの依存関係を追加する。
pom.xml
<!-- H2 データベース -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
<scope>runtime</scope>
</dependency>
H2DBのテーブル定義
H2DB(インメモリ)を使用したい場合、事前にスキーマ情報と初期データを準備する必要がある。
Spring JDBCに関する記事にて使用するH2DBについて、テーブルイメージと必要な資材を紹介する。
テーブルイメージ
用意するテーブルは以下のようなイメージとなる。
生徒情報テーブルと、生徒一人ひとりに紐づくテスト情報テーブルを用意する。
生徒情報テーブル
id | 学年 | 名前 | クラス名 | メモ |
---|---|---|---|---|
1 | 1 | 山田太郎 | 1-A | 良好な成績 |
2 | 2 | 佐藤花子 | 2-B | スポーツ万能 |
3 | 3 | 鈴木一郎 | 3-C | 芸術に秀でる |
テスト情報テーブル
id | 国語 | 算数 | 評価 | テスト実施日 | 生徒ID |
---|---|---|---|---|---|
1 | 80 | 70 | 良好 | 2023/5/22 | 1 |
2 | 90 | 65 | 優秀 | 2023/5/22 | 2 |
3 | 75 | 85 | 可 | 2023/5/22 | 3 |
4 | 85 | 90 | 非常に良い | 2023/9/30 | 1 |
5 | 60 | 80 | 普通 | 2023/9/30 | 2 |
6 | 85 | 90 | 非常に良い | 2023/9/30 | 3 |
テーブル定義
スキーマ情報と初期データはクラスパス上に格納する。
/resources/sql/schema.sql
-- 生徒テーブル
CREATE TABLE IF NOT EXISTS student (
id INT AUTO_INCREMENT PRIMARY KEY,
grade INT NOT NULL, -- 学年
name VARCHAR(30) NOT NULL, --名前
class_name VARCHAR(30) NOT NULL, -- クラス
memo TEXT -- メモ
);
-- テスト点数テーブル
CREATE TABLE IF NOT EXISTS test_point (
id INT AUTO_INCREMENT PRIMARY KEY,
japanese INT NOT NULL, -- 国語
mathematics INT NOT NULL, -- 算数
evaluation TEXT NOT NULL, -- 評価
test_date DATE NOT NULL, -- テスト実施日
student_id INT NOT NULL, -- 生徒ID(外部キー)
FOREIGN KEY (student_id) REFERENCES student(id)
);
/resources/sql/data.sql
-- 生徒情報
INSERT INTO student (grade, name, class_name, memo) VALUES (1, '山田太郎', '1-A', '良好な成績');
INSERT INTO student (grade, name, class_name, memo) VALUES (2, '佐藤花子', '2-B', 'スポーツ万能');
INSERT INTO student (grade, name, class_name, memo) VALUES (3, '鈴木一郎', '3-C', '芸術に秀でる');
-- テスト情報
INSERT INTO test_point (japanese, mathematics, evaluation, test_date, student_id) VALUES (80, 70, '良好', '2023-05-22', 1);
INSERT INTO test_point (japanese, mathematics, evaluation, test_date, student_id) VALUES (90, 65, '優秀', '2023-05-22', 2);
INSERT INTO test_point (japanese, mathematics, evaluation, test_date, student_id) VALUES (75, 85, '可', '2023-05-22', 3);
INSERT INTO test_point (japanese, mathematics, evaluation, test_date, student_id) VALUES (85, 90, '非常に良い', '2023-09-30', 1);
INSERT INTO test_point (japanese, mathematics, evaluation, test_date, student_id) VALUES (60, 80, '普通', '2023-09-30', 2);
INSERT INTO test_point (japanese, mathematics, evaluation, test_date, student_id) VALUES (85, 90, '非常に良い', '2023-09-30', 3);
テーブル情報の初期化
アプリケーション起動時、H2DBに対して用意しているスキーマ情報や初期データを適用させるため、Bean定義ファイルに以下のように記載する。
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
(略)
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:sql/schema.sql" />
<jdbc:script location="classpath:sql/data.sql" />
</jdbc:initialize-database>
(略)
上記のように<jdbc:initialize-database> タグを使用すると、Springフレームワークに組み込まれているJDBC名前空間を利用して、
アプリケーションの起動時にH2DBに対して初期DDLとデータを自動で適用させることができる。
エンティティ
最後に生徒情報とテスト情報のエンティティを作成する。
Student.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private int grade;
private String name;
private String className;
private String memo;
private List<TestPoint> tests;
}
TestPoint.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestPoint {
private int id;
private int japanese;
private int mathematics;
private String evaluation;
private Date testDate;
private int studentId;
}