(第12回) DBをMySQLに変更する【Spring Boot2で日記ウェブアプリ】

Spring Boot2.7で日記投稿ウェブアプリ入門の第12回です。今回はSpring Bootで使用しているDBをH2からMySQLへ切り替えます。Spring BootからMySQLの接続設定やSQLロギングについて説明します。

※ 本ページはプロモーションが含まれています。

動作環境と今回の目的

最終更新日:2023/5/28

前回は、Spring Boot日記ウェブアプリの編集画面と更新機能を作りました。CRUDでいうと、U(Update、データ更新)の部分です。 そして、簡単なSpring Bootアプリではありますが、これでDBと連携したCRUD機能の全ての開発が完了しました。
(第11回) 日記の編集画面と更新機能を追加、CRUDのU(Update、更新)【Spring Boot2で日記ウェブアプリ】

今回は、これまでDB(データベース)はH2を使用していましたが、DBをH2からMySQLヘ変更して、Spring BootからMySQLへの接続設定について説明します。

◾️動作環境やバージョンは以下の通りです。
OS:macOS Big Sur(バージョン11.7.2)
開発環境:Eclipse(Pleiades All in One、4.16(2020-06)、Java Full Edition版)
Spring Bootバージョン:2.7.6
Java:11
データベース:MySQL Community Edition 8.0.31
Bootstrap5.2.2

Spring BootのデータベースをH2からMySQLへ切り替える。MySQLを使ってDBデータを永続化する

ここまで開発してきたSpring Bootの日記ウェブアプリでは、DBはH2(メモリベース)を使用していました。H2はインストールする必要もないので、Spring BootなどのJava開発では手軽に使えるDBではありますが、いざ本格的にWebアプリやwebサイトを開発するとなるとあまり使用されないと思います。

また、H2をメモリベースで使用していたので、Spring Bootアプリを起動するたびにDBのテーブルやデータが初期化されるという使い方をしていました。

H2はメモリベースだけでなく、ファイルベースで使用してデータをファイルに保存して永続化する事もできます。H2をファイルベースで使用する方法については別ページで説明しているので、興味ある方は参考にしてください。
H2のデータをファイルに保存、データの永続化【Spring Boot2】

ですので、今回は使用しているDBをH2からMySQLヘ変更してみます。MySQLはWebアプリやWebサイトでよく使用されるDBの1つですし、仕事の開発プロジェクトだけでなく、個人で使っている人も結構いると思います。(WordPressで使われてるDBですし。)

これ以降は、MySQL環境がある事を前提として説明していきます。別ページでCommunity Edition版のMySQLのインストール方法について説明しているので、よければ参考にしてください。(Community EditionのMySQLは、GPLライセンスに従えばフリー(無料・無償)で使用する事ができる。)
MySQLのインストール【macOS】
MySQL8のインストール方法(ec2,CentOS7)

Windows環境の人も、ネットでMySQLのインストール方法について調べれば色々と情報があると思います。

Spring Bootで使用するMySQLのDB、テーブル、ユーザを作成する(事前準備)

Spring Bootアプリ側の設定をする前に、Spring Bootアプリで使用するMySQLのDB、テーブル、ユーザを作成しておきます。

rootユーザでMySQLにログインして、MySQLプロンプト上でdiarydbという名前のDBを作成します。

> create database diarydb;
次に、diarydbデータベースにdiaryテーブルを作成します。
> use diarydb;
〜
[diarydb]> create table diary (id integer auto_increment, bodytext varchar(255), create_datetime timestamp not null, primary key (id));

そして、diarydbデータベースを操作するためのMySQLユーザを新規作成します。ここではユーザ名はdiarydbuser、パスワードはdiarydbpassとしておきます。

> CREATE USER 'diarydbuser'@'localhost' IDENTIFIED BY 'diarydbpass';
> GRANT ALL PRIVILEGES ON `diarydb`.* TO "diarydbuser"@"localhost";

1行目の「CREATE USER 'diarydbuser'@'localhost' ~ 」は、「'diarydbuser'@'localhost'」というユーザを作成しています。
このlocalhostは、MySQLサーバと同じホスト(PC)という意味です。

また、2行目の「GRANT ALL PRIVILEGES ON `diarydb`.* TO "diarydbuser"@"localhost";」は、作成した「'diarydbuser'@'localhost'」ユーザに、diarydbデータベースの操作権限を全て付与するという意味です。

ですので、MySQLサーバとSpring Bootアプリが同じホスト(PC)にあれば、Spring BootアプリからdiarydbuserユーザでMySQLサーバへアクセスしてdiarydbデータベースを操作できるようになります。

ちなみにMySQLのユーザ一覧は、mysql.user(MySQLデータベースのuserテーブル)で確認できます。

> select user, host from mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| diarydbuser      | localhost |
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+

MySQLの新規ユーザ(diarydbuser)を作成したら、diarydbuserでmysqlログインできるかを確認しておきましょう。

$ mysql -u diarydbuser -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
〜
そして、diarydbuserユーザでログインしたら、MySQLプロンプト上でSHOW GRANTSコマンドで自分に付与されている権限が確認できます。
> SHOW GRANTS FOR current_user();
+------------------------------------------------------------------+
| Grants for diarydbuser@localhost                                 |
+------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `diarydbuser`@`localhost`                  |
| GRANT ALL PRIVILEGES ON `diarydb`.* TO `diarydbuser`@`localhost` |
+------------------------------------------------------------------+

これでSpring Bootアプリで使用するMySQLのDB、テーブル、ユーザの準備ができました。

■別ホスト(PC)から、MySQLサーバへ接続できるようにするには
上でも説明しましたが、作成した「'diarydbuser'@'localhost'」ユーザはMySQLサーバと同じホスト(PC)からしか接続できません。

ですので、もしもSpring Bootアプリのあるホスト(PC)とMySQLサーバのホスト(PC)が別々の環境だとSpring BootからMySQLサーバへ接続できないので、MySQLサーバにリモートホストから接続できるユーザを作成する必要があります。

> CREATE USER 'diarydbuser'@'%' IDENTIFIED BY 'diarydbpass';
> GRANT ALL PRIVILEGES ON `diarydb`.* TO "diarydbuser"@"%";
作成したユーザは「'diarydbuser'@'%'」なので、diarydbuserユーザは全てのホストからMySQLサーバへ接続できるようになります。

全てのホストからだとセキュリティ的に心配な場合、ホストをIPアドレスとかで指定するのも良いと思います。この辺のMySQLユーザの作成の話は別ページでもう少し詳しく書いているので、そちらも参考にしてください。
MySQL(MariaDB)にmysqlコマンドでリモート接続する

■作成するMySQLユーザのdiarydbデータベースの操作権限をCRUD SQLだけにしたい場合
上でも説明しましたが、作成した「`diarydbuser`@`localhost` 」ユーザに付与した権限は、diarydbデータベースに対する全ての操作権限です。もしも、全ての操作権限は必要なくCRUD SQL(SELECT、INSERT、UPDTE、DELTE)だけで十分なら、そういう権限を付与した方がセキュリティ的にも良いと思います。

> GRANT SELECT, INSERT, UPDATE, DELETE ON `diarydb`.* TO "diarydbuser"@"localhost";
ただこの権限のユーザだと、当然Spring Bootアプリ起動時などにテーブル作成のSQL(create table ~)を実行できなくなります。

ちなみに作成したMySQLユーザを削除したい場合、drop userでできます(rootユーザで実行する)。

> drop user 'diarydbuser'@'localhost';

Spring Bootのpom.xmlを編集して、MySQLドライバーを使用できるようにする

次に、Spring Bootプロジェクトのpom.xmlファイルの編集です。

Spring BootからMySQLを使用するのでMySQL Driver(ドライバー)を利用できるように、MySQLドライバーライブラリのdependencyタグを追加します。

<dependency>
	<groupId>com.mysql</groupId>
	<artifactId>mysql-connector-j</artifactId>
	<scope>runtime</scope>
</dependency>
pom.xmlファイルを直接編集して追加しても良いですし、Eclipse上でSpring Bootプロジェクトを右クリック->Spring->スターターの編集を選択してSpring Bootスターター画面を開いて、そこからMySQL Driverを追加しても良いです。

少し文言が違うけど下記のdependencyタグを追加しても、MySQLドライバーが使えるようになります。

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

DBをH2からMySQLへ変更するので、今まで使っていたH2 Databaseライブラリのdependencyタグは削除してもいいです。

<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
	<scope>runtime</scope>
</dependency>
ただ、このタグを削除するとH2 Consoleも使用できなくなります。MySQLに変更してもウェブ上でのH2 Consoleが使えるのは便利かもしれませんが、MySQLのプロンプト上でSQL操作すれば十分だからH2 Consoleは使わない、必要ないという人も多いと思うので、それならH2 Databaseライブラリは削除しちゃって良いと思います。

あと、SQLロギングのために追加していたLog4jdbc-log4j2ライブラリのdependencyタグを削除します。

<dependency>
	<groupId>org.bgee.log4jdbc-log4j2</groupId>
	<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
	<version>1.16</version>
</dependency>
これは、このdependencyタグがあると、Spring Bootアプリ起動時にEclipseのコンソール上にこのエラーログが出るためです。
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
このエラーログの詳細については別ページで書いていますので、そちらを参考にしてください。
Spring Boot起動時にMySQL Driverエラーが発生

pom.xmlファイルの編集は以上です。

Spring Bootのapplication.propertiesの編集。MySQL接続設定やSQLログ出力の設定など

次に、Spring Bootアプリの設定ファイルのapplication.propertiesの編集です。

H2の接続設定部分を削除して、MySQLの接続設定を追加します。
■編集前

spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:h2:mem:diarydb
■編集後
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/diarydb
spring.datasource.username=diarydbuser
spring.datasource.password=diarydbpass

"spring.datasource.url"は、DBの接続URLです。自分のPCにインストールしたMySQLサーバのdiarydbという名前のDBに接続するように設定しています。3306はMySQLサーバのポート番号です。MySQLサーバが使用しているポート番号は、MySQLプロンプト上でshow variablesコマンドを実行すれば確認できます。

> show variables like 'port';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 3306  |
+---------------+-------+

"spring.datasource.username"と"spring.datasource.password"は、MySQLのユーザ名とパスワードですので、各自の環境で設定してください。

そして、"spring.datasource.driver-class-name"はMySQLドライバーを指定します。

ちなみに"spring.datasource.driver-class-name"ですが、OSやMySQLのバージョンなどの環境にもよると思いますが、私の環境では"spring.datasource.driver-class-name"を指定しなくてもSpring Bootアプリは起動して動作しました。ただ指定しても問題ないので、明示的に指定しておいた方が解りやすくて良いかもしれませんね。

この設定でMySQLと連携してSpring Bootアプリを起動・動作する事ができますが、もう少しプロパティファイルの設定をします。

プログラミング開発時のデバッグやロギングの為に、Spring Bootウェブアプリで実行されるSQLのログをEclipseのコンソールに出力したい場合、spring.jpa.show-sqlプロパティを設定します。

spring.jpa.show-sql=true
これで実際にSpring Bootアプリを起動して動作させると、こんな感じのSQLログが出力されました。
Hibernate: select diary0_.id as id1_0_, diary0_.bodytext as bodytext2_0_, diary0_.create_datetime as create_d3_0_ from diary diary0_
Hibernate: select diary0_.id as id1_0_0_, diary0_.bodytext as bodytext2_0_0_, diary0_.create_datetime as create_d3_0_0_ from diary diary0_ where diary0_.id=?
Hibernate: delete from diary where id=?
Hibernate: select diary0_.id as id1_0_, diary0_.bodytext as bodytext2_0_, diary0_.create_datetime as create_d3_0_ from diary diary0_
Hibernate: insert into diary (bodytext, create_datetime) values (?, ?)
Hibernate: update diary set bodytext=?, create_datetime=? where id=?
HibernateがSQLロギングをしてくれる事がわかります。SQLの変数はプレースホルダーの状態になっていますが、これでも十分デバッグには役立ちそうです。

あと、本番環境ではなく開発環境の話で、もしもSpring Boot起動時にDBデータの初期化をしたい場合、プロパティファイルで"spring.sql.init.*"を設定します。
(*このデータ初期化の設定は、DBがH2の時と同じ。)

spring.sql.init.mode=always
spring.sql.init.data-locations=classpath:data.sql
spring.sql.init.schema-locations=classpath:schema.sql

そして、src/main/resourcesディレクトリにschema.sqlとdata.sqlファイルを作成して、schema.sqlにDBのテーブルを生成するSQL(DDL)、data.sqlにテーブルデータを生成するSQL(DML)を書きます。

■schema.sql

create table if not exists diary (id integer auto_increment, bodytext varchar(255), create_datetime timestamp not null, primary key (id));
■data.sql
INSERT INTO diary(bodytext, create_datetime) VALUES('今日は晴れ。コメント1', LOCALTIME());
INSERT INTO diary(bodytext, create_datetime) VALUES('コメント2', LOCALTIME());

これで、Spring Boot起動時にschema.sqlとdata.sql内のSQLが実行されて、diaryテーブル生成とテーブルデータの初期化ができます。(schema.sqlのcreate文にはif not existsが付いているので、DBにdiaryテーブルが無い場合のみ実行される。)

ちなみにファイル名がschema.sqlとdata.sqlであれば、"spring.sql.init.mode=always"だけ設定していれば、"spring.sql.init.data-locations"と"spring.sql.init.schema-locations"を設定しなくてもschema.sqlとdata.sqlのSQLを実行してくれます。ただ明示的にこの2つも設定しておいた方が解りやすいと思います。

あと、spring.jpa.hibernate.ddl-autoプロパティは、MySQLの場合はデフォルトでnone設定です(noneはDBに対して特に何もしない)。none設定で良ければ指定する必要はないけど、これも設定で明示して良いかもしれません。

spring.jpa.hibernate.ddl-auto=none

Spring BootとMySQLの連携の設定は以上です。Spring Bootアプリを起動して動作確認しましょう。

macとLinuxサーバ上にSpring Boot + MySQLの実行環境を構築する

macOSとLinuxサーバ上でMySQLと連携したSpring Bootアプリの実行環境を構築したい場合、Java(JRE)とMySQLのインストールが必要です。

別ページでOpenJDK(JRE)とコミュニティ版MySQLをインストールしてDBと連携したSpring Bootの実行環境を作る手順について説明しているので、参考にしてください。
Spring Boot + MySQL(MariaDB)の実行環境を作る

OpenJDKとコミュニティ版MySQLはどちらもオープンソースでライセンスに従えば無償(フリー)で使う事ができます。

Spring BootからMariaDBを使う

MariaDBデータベースは、MySQLから派生したオープンソースのDBで、もちろんSpring BootからMariaDBを使う事ができます。

Spring Bootのライブラリを見ると「MariaDB Driver」があったので、やっぱり接続ドライバと接続設定をMySQLからMariaDBに切り替える必要があるだろうなと思いつつ、MariaDBはMySQLと互換性があるという話を聞くので、もしかしたらMySQLの接続設定でそのままMariaDBが使えるかもしれないと考え、試しにMySQLドライバーのままでSpring BootからMariaDBを使ってみたら、問題なく起動・動作しました!さすが置き換え可能な互換性があると言われるだけはあります。

ただ、これは私の動作環境だけで、動作環境やバージョンによっては無理かもしれないし、「MariaDB Driver」ライブラリもあるんだから、Spring BootからMariaDBを使う場合は、ちゃんとMariaDBドライバーを使って接続設定をした方が良い気がします。

Spring BootでMariaDB Driverライブラリを使ったMariaDBの接続設定については、次回の記事で説明しています。

最後に。次回(DBをMariaDBへ変更)について

以上今回は、Spring Bootで使用するDBをH2からMySQLに変更してみました。MySQLさえ用意すれば、pom.xmlとapplication.propertiesの2つのファイルを少し編集するだけで、簡単にSpring BootとMySQLの連携をして使う事ができます。

仕事でSpring Bootを使うからもっとしっかり勉強しておきたい、Spring Bootのログイン認証周りやセキュリティ面なども抑えておきたい、JavaプログラマになりたいからそのためにJavaで人気のフレームワークのSpring Bootの知識とスキルを身につけたい方は、体系的に学習できる本を読んで学習するのが良いと思います。

(広告)AmazonでSpring Boot3(バージョン3系)の初心者向け入門書を探す!本でSpring Bootプログラミング開発を体系的に勉強する!

次回は、Spring Bootの日記ウェブアプリで使用するデータベースをMariaDBに設定する方法について説明します。
(第13回) Spring Bootで使うDBをMariaDBに変更【Spring Boot2で日記ウェブアプリ】

Eclipse上でSpring BootプロジェクトをGit(gitコマンド)で管理する方法を別ページで説明していますので、興味のある方は参考にしてください。GitやGitHubはチームで使用される事が多いツールですが、個人(独学)でプログラミング開発する時でも非常に便利でプログラミングの効率が良くなると思います。
EclipseのSpring BootをGitで管理する。更にリモート環境でGit共有リポジトリ管理も