【第2回】Spring bootで運動記録をDBに記録してみた(DB作成編)
IT技術
【第2回】Springbootを使って、DBとの連携システムを考える
前回は簡単な画面表示をするところまで説明しました。
今回はDB(データベース)の設定をしていきたいと思います。
DBにもいろいろと種類はありますが、
まずは手間が少ない 「h2 database」 を利用してみたいと思います。
前回の記事はこちら
h2 databaseでDBを作成する
pom.xmlの設定
前回の記事で、DBを利用するためにプロジェクト作成時に
「JDBC API」 と 「h2 database」 をライブラリ指定したかと思います。
指定してあればpom.xmlに以下の記述がされているはずです。
もし無ければ追記してください。
1<dependency>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-jdbc</artifactId>
4</dependency>
5
6<dependency>
7 <groupId>com.h2database</groupId>
8 <artifactId>h2</artifactId>
9 <scope>runtime</scope>
10</dependency>
application.ymlの設定
次にapplication.ymlにDB設定をしていきます。
1spring:
2 datasource:
3 driver-class-name: org.h2.Driver
4 url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false
5 username: sa
6 password:
7 initialization-mode: always
「spring.datasource」 に一通りの設定を記述しています。
「driver-class-name」 でドライバのクラス名を指定してます。
urlにはDBの種類、DB名とオプションを記載してあります。
今回は 「jdbc:h2:mem:testdb;」 でh2にtestdbという名前のDBを
mem指定でインメモリデータベースとして準備しています。
インメモリデータベースはSpringboot起動中に使えるメモリ上のデータベースです。
この設定だと、Springbootを停止するとメモリは破棄されます。
インメモリの場合、通常h2は接続が切れるとデータベースをドロップします。
それを防ぐために「DB_CLOSE_DELAY=-1;」追記します。
また、「DB_CLOSE_ON_EXIT=false」 で
VM終了時の自動データベースクローズを無効にしています。
あとは接続するためのusernameとpasswordを設定します。
「initialization-mode: always」については後で説明します。
h2コンソールの設定
h2コンソールを利用することによって、DBの確認がしやすくなります。
application.ymlに以下を追記します。
1spring:
2 datasource:
3(中略)
4
5 h2:
6 console:
7 enabled: true
8 path: /h2-console
「spring.h2.console」に一通りの設定を記述しています。
「enabled」は、コンソールの利用有無を設定しています。
trueなら利用、falseなら利用しない、となります。
「path」は、H2コンソールを表示するURLパスとなります。
上記のように「path: /h2-console」と設定した場合、
ローカル起動して「http://localhost:8080/h2-console」にアクセスすると
h2コンソールが表示されます。
この画面にapplication.ymlで設定した情報を入力して
「Connect」を押すとDBの状態が見れます。
今はまだDBの定義もしていないので、この画面が見えるだけで良いです。
DBのテーブルを準備する
次にDBのテーブルを準備します。
いくつか方法がありますので、順番に紹介していきます。
JPAによるテーブルの設定
application.ymlに「spring.jpa.」からの設定を追記します。
これによってSQLのお手伝いをしてくれる設定を取り込みます。
1spring:
2 (中略)
3 jpa:
4 show-sql: true
5 hibernate:
6 ddl-auto: cleate
「show-sql」をtrueにすると、生成されたSQLがコンソール等で表示されるようになります。
「hibernate.ddl-auto」を「cleate」に設定しておくと
「@entity」で定義されたクラスを読み取って、
自動的にクラス名のテーブルで、変数をカラムとして作成してくれるようになります。
例えばクラス名がProgramで、その中に変数名id、nameがあるとします。
このクラスに@Entity アノテーションを付けて起動すると、
カラムidとnameが存在するprogramテーブルが自動的に作られます。
1<クラス例>
2@Entity
3public class Program {
4 @Id
5 private Long id;
6
7 private String name;
8
9 public Long getId() {
10 return id;
11 }
12・・・(以降は略)
この時 show-sql を設定していると、起動時に以下のようなログが表示されるので、動きがわかりやすいです。
1<コンソールログ>
2Hibernate: drop table if exists program CASCADE
3Hibernate: create table program (〜・・・
schema.sqlによるテーブルの設定
次に「schema.sql」を利用したテーブル設定の紹介です。
先に記述していた 「initialization-mode: always」をapplication.ymlに設定すると、
起動時に決められた配置にあるSQLファイルを読み込んでくれるようになります。
(前述の記載例を参照)
読み込むために schema.sql という名前のファイルを
resourcesディレクトリ直下に配置し、
その中にCREATE文など必要なものを記載していきます。
1CREATE TABLE IF NOT EXISTS program (
2 id IDENTITY NOT NULL PRIMARY KEY,
3 name VARCHAR(255) NOT NULL,
4 unit VARCHAR(255) NOT NULL,
5 programset BOOLEAN,
6 updatetime TIMESTAMP DEFAULT NOW() NOT NULL
7);
8
9CREATE TABLE IF NOT EXISTS achievement (
10 achievement_id IDENTITY NOT NULL PRIMARY KEY,
11 program_id NUMERIC NOT NULL,
12 practice_num NUMERIC NOT NULL,
13 practice_set_num NUMERIC,
14 practice_time TIMESTAMP DEFAULT NOW() NOT NULL,
15 update_time TIMESTAMP DEFAULT NOW() NOT NULL
16);
設定の仕方によっては起動のたびに呼ばれるので重複エラーが起きないように
「CREATE TABLE IF NOT EXISTS 〜」としておくと良いです。
(記載されているテーブル名が存在しなければテーブルを作る、という意味です)
また「data.sql」という名前のファイルを上記と同じところに配置し、
中身にINSERT文を記載しておくことによって
起動時にデータを入れてくれるようになります。
1-- program
2INSERT INTO program(name, unit, programset) VALUES ('腹筋', '回', true);
3INSERT INTO program(name, unit, programset) VALUES ('背筋', '回', true);
4INSERT INTO program(name, unit, programset) VALUES ('ランニング', 'm', false);
5INSERT INTO program(name, unit, programset) VALUES ('てすと', 'テスト', false);
6
7-- achievement
8INSERT INTO achievement(program_id, practice_num, practice_set_num) VALUES (1, 30, 3);
9INSERT INTO achievement(program_id, practice_num, practice_set_num) VALUES (2, 30, 3);
10INSERT INTO achievement(program_id, practice_num) VALUES (3, 1500);
上記テーブル設定についての注意点
では「ddl-auto」を有効にしつつ、「schema.sql」を設定した場合はどうなるでしょうか?
この場合で起動すると、「schema.sql」「data.sql」が実行されてテーブルとデータが出来るも、
そのあとに「ddl-auto」の機能で一度テーブルを消してから
@Entityの情報を読み取ってテーブルを作る、
といった動きになり、「schema.sql」「data.sql」は意味が無くなります。
ですので、用途に合わせてどのようにテーブルの準備するかは検討しておくと良いでしょう。
今回は schema.sql での実装
今回はSQLの勉強も兼ねて、「schema.sql」でテーブル準備をしたいと思います。
SQLの中身は上記の例で記載したとおり、「program」「achievement」の2テーブルを作成し、
「data.sql」に記載したデータを初期値として起動時に登録する形で進めます。
そのために今の「ddl-auto」の設定を「cleate」から「none」に書き換えて無効にします。
「ddl-auto」が有効の時の勉強も別途する予定なので、記述自体はひとまず残しておく方向です。
起動してh2コンソールでテーブルを確認する
では、上記の「schema.sql」「data.sql」を準備した状態で起動してみます。
起動後、h2コンソールを開きます。、データが入っていればOKです。
先に書いた通り、application.ymlに記載した情報を入力して、Connectボタンを押します。
画面が切り替わり左側のサイドメニューにtestdbのデータベース名があり、
「schema.sql」で記載したテーブル名があればOKです。
「data.sql」もあればそこで記載したレコードが反映されているか、
真ん中のテキストエリアにSQL文を書き込んで、「Run」ボタンを押して実行してみてください。
ひとまず、「SELECT * FROM PROGRAM」で、PROGRAMテーブルの中身を見てみます。
SQLの結果、正常にデータが表示されていればOKです。
さて、これで最低限のDBの準備が出来ました。
次からはこのDBを利用して、画面に表示したりデータの変更をしたりしていきたいと思います。
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
元ファストフード店長代理のJava系ITエンジニア。 Webサイト系の開発や運用をいくらか経験し、 現在はAndroidアプリ開発を主に担当したり。 休みの日はゲームとか風景写真撮りに行ったりとかマラソンしたりとか。