docker-compose で Spring-Boot を起動して MyBatis を使って MySQL からデータを取ってくるまで
ディレクトリ構成
Docker
├ docker-compose.yml
├ mysql # DB永続化のためのファイル
| ├ sql - mysql.cnf
| | └ init.sql
| └ settings # ここはコンテナができ次第自動的に作成される
|
└ spring # スプリングのプロジェクト
└ gradle
└ gradlew
└ src ...
開発手順
- SpringBoot プロジェクトを作成し適切なディレクトリに配置
- docker-compose.yml を起動(コンテナが 2 つ起動)
- gradle のビルド
- java の実行
docker-compose.yml
version: "3"
services:
# SQLのサービス
db:
image: mysql:8
container_name: "spring_db"
ports:
- "3306:3306"
volumes:
- ./mysql/sql/:/docker-entrypoint-initdb.d
- ./mysql/settings/:/var/lib/mysql
- ./mysql/sql/mysql.cnf:/etc/mysql/conf.d/my.cnf
environment:
MYSQL_DATABASE: "sample" # この場合sampleというデータベースが作成されます
MYSQL_ROOT_USER: "root" # rootユーザーはパスワードを設定しないとエラーでます
MYSQL_ROOT_PASSWORD: "root"
TZ: "Asia/Tokyo"
# springアプリケーションのサービス
spring:
image: openjdk:11
container_name: "spring"
restart: always
ports:
- "9090:8080"
tty: true
depends_on:
- db
volumes:
- ./my-workbook:/srv:cached
working_dir: /srv
init.sql
CREATE DATABASE IF NOT EXISTS sample;
CREATE TABLE user(
user_id serial primary key,
user_name char(16) NOT NULL,
password char(16) NOT NULL
);
INSERT INTO user(user_name, password) VALUES('user', 'password');
mysql.cnf
デフォルトが latin1 という文字コードのため日本語対応させる
※なぜか Spring 側で日本語は入れられますが、init.sql 等で記述した日本語は入りません。
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
[client]
default-character-set=utf8mb4
application.properties
ローカルと SQL の接続先が変わるので注意
spring.datasource.url=jdbc:mysql://db:3306/sample
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.configuration.map-underscore-to-camel-case=true
spring.datasource.url=jdbc:mysql://db:3306/sample
について、db
は docker-compose.yml のサービス名を指定。最後のsample
は参照するデータベース名。
実行
Docker コンテナの立ち上げ
docker-compose.yml がある階層に移動して
docker compose up -d
Gradle のビルド
ビルドのためにコンテナ内に入る
docker compose exec spring bash
ビルド ※時間がかかります
sh gradlew build
SpringBoot プロジェクトの実行
java -jar build/libs/spring-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.5.7)
spring 実行画面が出たら docker-compose.yml で指定した 9090 ポートにアクセスしてみましょう
データベースに INSERT した user_name が画面に出力するようにしているので、成功しました。
ハマったところ
-
コンテナは正常に立ち上がってるのに連携ができない
RowMapper は MyBatis を利用しており、xml ファイルを使用して SQL を書いていました。
問題はそのディレクトリ配置で、Java 側の HogeMapper.java ファイルと同じパッケージ内に HogeMapper.xml を配置しており、ローカルでは正常に動作するのですが、コンテナ内ではしっかりとパスを指定してあげるか、resources 内に HogeMapper.java と同じパッケージ内(co.jp.example.mapper 等)に配置してあげる必要があるみたいです。 -
MySQL に日本語が入らない
これは上記 mysql.cnf で文字コードを変えることで解決しました。試しに新しいタブを開き、
docker exec -it spring_db bash
で MySQL のコンテナに入り、mysql -u root -proot
を実行してからshow variables like '%char%';
を入力すると、utf-8mb4 に変わっていると思います。