ふるてつのぶろぐ

福岡在住のエンジニアです。

写真提供:福岡市

いまだにJava 8 備忘録 - MyBatis Genaratorの使い方と Flyway

今日すること

こんにちはふるてつです。
ちょっとした新シリーズになります。
最近業務外でJavaを良く触るので、忘れそうな内容を備忘録として書きとめておきたいと思います。

f:id:tetsufuru:20191019103646p:plain

タイトルの通りおじさんはいまだにJava8です。
基本的にはいつもSpring Bootを使っています。
ちなみに業務でもJavaですが、コードを書く機会が減ったので、ほぼほぼ家に帰ってからさわる毎日です✨
今回は数年ぶりにMyBatisを使ったのでそのことを記事にしました。

MyBatisとは昔からあるO/Rマッパーの事です。
相当昔からあり、一時期はどこの客先に行ってもこれを使っていたように思います。
f:id:tetsufuru:20191019103308p:plain
https://mybatis.org/mybatis-3/ja/index.html

新規プロジェクトの作成

まずはEclipseにて新しいプロジェクトを作成します。
STSプラグインは事前にダウンロードしておきます)

「新規」 ⇒ 「その他」
f:id:tetsufuru:20191019105051p:plain

そして「Springスターター・プロジェクト」を選択します。 f:id:tetsufuru:20191019105137p:plain:w400

わたしはGradleを良く使います。
f:id:tetsufuru:20191019105533p:plain:w400

プロジェクトの依存関係ですが、 FlywayMyBatisH2Spring WebLombokSpring Dev Toolsを選びます。
f:id:tetsufuru:20191019105714p:plain:w400

このまますすめて完了。
f:id:tetsufuru:20191019105947p:plain:w400

下記のようにプロジェクトが出来ました。
f:id:tetsufuru:20191019110031p:plain

H2環境の設定

つぎはH2を使用するための設定をEclipseapplication.propertiesに追加します。 f:id:tetsufuru:20191019110523p:plain

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:./h2db/sampledb
spring.datasource.username=username
spring.datasource.password=password

DDLの作成

次にsrc/main/resourcesの配下にdb/migrationフォルダを作り、そこに DDL文を配置します。
上記の写真ではV1__create_schema_for_domain.sqlという名前になっています。
この状態でいったんEclipseを起動します。
起動するとFlywayが勝手にDDL文を流してくれ、テーブルがH2の中にできます。
正常に起動したらいったん終了しておきます。
f:id:tetsufuru:20191019111326p:plain

MyBatis Generatorのインストール

テーブルが無事にできたところでMyBatis GenaratorEclipseにインストールします。
マーケットプレイスからインストールします。
(下記の写真はインストール後になります) f:id:tetsufuru:20191019111515p:plain:w400

generator config の設定

generationConfig.xmlファイルをリソースの中に作成します。
リソースであれば場所はどこでも構わないと思います。
f:id:tetsufuru:20191019111646p:plain:w400

f:id:tetsufuru:20191019111843p:plain

細かい設定内容は下記ですが、若干コツがあります。
Xmlファイルの出力パス( )とMapperの出力パス( )とをそろえると、 いい具合にMyBatisがお互いを関連づけて認識してくれます。
ことなる場合、ちょっと忘れましたが、なにがしらの設定を追記しなければなりません。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
  <context id="handsOnTables" targetRuntime="MyBatis3">

    <!-- Connection Settings -->
    <jdbcConnection driverClass="org.h2.Driver"
        connectionURL="jdbc:h2:../workspace/mybatis-demo/h2db/sampledb"
        userId="username"
        password="password">
    </jdbcConnection>

    <!-- Entity Models -->
    <javaModelGenerator targetPackage="com.example.demo.entity.domain" targetProject="mybatis-demo/src/main/java">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>

    <!-- Sql Xml files -->
    <sqlMapGenerator targetPackage="com.example.demo.mybatis" targetProject="mybatis-demo/src/main/resources">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>

    <!-- Mappers -->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.demo.mybatis" targetProject="mybatis-demo/src/main/java">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>

    <!-- Target tables -->
    <table schema="" tableName="USER_MST">
      <property name="mapUnderscoreToCamelCase" value="true" />
    </table>
    <table schema="" tableName="PRODUCT_MST">
      <property name="mapUnderscoreToCamelCase" value="true" />
    </table>
    <table schema="" tableName="PRODUCT_STOCK_MST">
      <property name="mapUnderscoreToCamelCase" value="true" />
    </table>
    <table schema="" tableName="PRODUCT_PURCHASE_TBL">
      <property name="mapUnderscoreToCamelCase" value="true" />
    </table>
    <table schema="" tableName="SUB_MENU_MST">
      <property name="mapUnderscoreToCamelCase" value="true" />
    </table>
    <table schema="" tableName="MENU_MST">
      <property name="mapUnderscoreToCamelCase" value="true" />
    </table>

  </context>
</generatorConfiguration>

MyBatis Generatorの実行

Eclipseのメニュー から 「実行」 ⇒ 「実行環境」を選択します。 f:id:tetsufuru:20191019113149p:plain 下記の実行構成画面でMyBatis Generatorを右クリック ⇒ 「新規作成」を選びます。
f:id:tetsufuru:20191019113544p:plain:w400

「名前」を入力し、「構成ファイル」はワークスペースから先ほどのgenerationConfig.xmlファイルを選択します。
f:id:tetsufuru:20191019114417p:plain:w400

Eclipseの画面左下のランナーに「MyBatis Generator」が表示されるようになりました。
これを右クリック ⇒ 「実行」でgeneratorが起動します。
f:id:tetsufuru:20191019114949p:plain

Configで設定した場所にentityが出来ました。 f:id:tetsufuru:20191019115221p:plain

Mapperができました。
f:id:tetsufuru:20191019115303p:plain

Xmlファイルができました。
下記ファイルのなかに自動生成されたSQL文が入っています。
自作のSQLを実行したい場合は、こちらに追記し、上記の Mapperに呼び出し用のメソッドを追加します。
ちなみに自動生成をやり直しても自作部分は消えないようになっています。
f:id:tetsufuru:20191019115341p:plain

初期データの投入

では少し試してみたいので初期データを投入してみます。 V2__import-initial-data.sqlというファイルを追加して、そのなかに初期データのInsert文を追加します。
これもまた次回Eclipseを起動したときにFlywayが流してくれます。
f:id:tetsufuru:20191019120453p:plain

H2からデータを取得

では簡単なコントローラとサービスを作ってMyBatisを試してみます。 まずコントローラを作ります。
f:id:tetsufuru:20191019120823p:plain

次にサービスを作ります。
f:id:tetsufuru:20191019121006p:plain

サービスの細かいコードは下記です。

package com.example.demo.service.rest;        
        
import java.util.List;      
        
import org.springframework.stereotype.Service;      
        
import com.example.demo.entity.domain.UserMst;      
import com.example.demo.entity.domain.UserMstExample;       
import com.example.demo.mybatis.UserMstMapper;      
        
import lombok.RequiredArgsConstructor;      
        
@Service        
@RequiredArgsConstructor        
public class MyBatisTestRestService {       
        
    private final UserMstMapper userMstMapper;  
        
    public void myBatisTest() { 
        
        // 例1)主キーで検索
        UserMst userMst = userMstMapper.selectByPrimaryKey(Long.valueOf(1));
        
        System.out.println("UserSeq:" + userMst.getUserSeq());
        System.out.println("UserName:" + userMst.getUserName());
        
        //  例2)条件を指定して検索
        UserMstExample userMstExample = new UserMstExample();
        userMstExample.createCriteria().andUserAccountEqualTo("user01");
        List userMsts = userMstMapper.selectByExample(userMstExample);
        
        System.out.println("UserSeq:" + userMsts.get(0).getUserSeq());
        System.out.println("UserName:" + userMsts.get(0).getUserName());
        
    }   
        
}       

ユーザーマスターテーブルからデータを取得するだけのコードになります。
まずはUserMstMapper をDIします。 例1のように、主キーで検索したい時はそれ専用に自動生成されたメソッドがあります。
そちらを使ってUserMst のエンティティを取得します、このあたりはどこのO/Rマッパーも同じかと思います。

例2のように条件を指定したい場合はExampleを使います。
これまでの客先でも特に使用していなかったのですが、今回すこしさわってみてかなり楽できることを発見しました。
ちなみに操作方法はまず、UserMstExample のインスタンスを作り、
userMstExample.createCriteria().andUserAccountEqualTo("user01");のようにアカウントに対する検索条件を追加します。
このインスタンスをselectByExampleのメソッドの引数に渡すと List が返ってきます。
なかなからくちんですね、もっと前に気づくべきでした😊

気をつけること

ひとつだけ気をつけることがあります。
このまま実行すると起動時にエラーが出ます。
f:id:tetsufuru:20191019122945p:plain

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.example.demo.service.rest.MyBatisTestRestService required a bean of type 'com.example.demo.mybatis.UserMstMapper' that could not be found.

Action:

Consider defining a bean of type 'com.example.demo.mybatis.UserMstMapper' in your configuration.

上記のメッセージは昔も出ていた気がします。
どうやって動くようにしていたかもう忘れてしまいましたので、 ネットでしらべて下記のようにアプリケーションの起動メソッドに@MapperScanを追加しました。
f:id:tetsufuru:20191019123341p:plain

参考サイト:https://qiita.com/matyahiko2831/items/d32039aef5f508408b42

動かしてみる

ではコントローラ経由で先ほどのサービスを動かしてみます。
コントローラの呼び出しは Postman を使います。
f:id:tetsufuru:20191019124126p:plain

下のような感じでユーザマスタに登録したデータを検索できました。
ログが出ています。
これで無事動くようになりました。
f:id:tetsufuru:20191019124238p:plain

感想


今回はMyBatisの導入について書きました。
MyBatis Generatorのことなど、わたし絶対にすぐ忘れるので書きとめてみました。

ふるっと思われた方もいらっしゃると思いますが、ご勘弁ください。
Spring JPAjOOQなど最近のもわからなくはないのですが、 SQLをゴリゴリ書きたいわたしにはやはりMyBatisが使いやすそうです。

そろそろ秋ですね、みなさま風邪をひかないようご注意ください。

それではまた😎