LoginSignup
21
16

More than 1 year has passed since last update.

Spring-Boot + MySQL + MyBatisを dockerで実行する

Last updated at Posted at 2021-12-23

docker-compose で Spring-Boot を起動して MyBatis を使って MySQL からデータを取ってくるまで

ディレクトリ構成

Docker
├ docker-compose.yml
├ mysql # DB永続化のためのファイル
|   ├ sql - mysql.cnf
|   |     └ init.sql
|   └ settings # ここはコンテナができ次第自動的に作成される
|
└ spring # スプリングのプロジェクト
    └ gradle
    └ gradlew
    └ src ...

開発手順

  1. SpringBoot プロジェクトを作成し適切なディレクトリに配置
  2. docker-compose.yml を起動(コンテナが 2 つ起動)
  3. gradle のビルド
  4. java の実行

docker-compose.yml

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

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 等で記述した日本語は入りません。

mysql.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

[client]
default-character-set=utf8mb4

application.properties

ローカルと SQL の接続先が変わるので注意

application.properties
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 が画面に出力するようにしているので、成功しました。

スクリーンショット 2021-12-23 16.33.37.png

ハマったところ

  • コンテナは正常に立ち上がってるのに連携ができない

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 に変わっていると思います。

21
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
16