Spring Boot から MyBatis を利用するための設定 (Gradle/MySQL)
[最終更新] (2019/05/31 01:29:59)
ここは
趣味のプログラミングを楽しむための情報共有サービス。記事の一部は有料設定にして公開できます。 詳しくはこちらをクリック📝
最近の投稿
注目の記事

概要

こちらのページで使い方を把握した MyBatis を、こちらのページで使い方を把握した Spring Boot で利用するための基本的な設定およびサンプルコードをまとめます。サンプルコードにおいては、特に MySQL を対象とします。

公式の解説動画

Spring Tips: MyBatis

サンプルプロジェクト構成

基本的な Gradle プロジェクトです。

.
|-- build.gradle
|-- gradle
|   `-- wrapper
|       |-- gradle-wrapper.jar
|       `-- gradle-wrapper.properties
|-- gradlew
|-- gradlew.bat
`-- src
    `-- main
        |-- java
        |   `-- hello
        |       |-- Application.java
        |       |-- City.java
        |       |-- CityMapper.java
        |       `-- HelloController.java
        `-- resources
            |-- application.yml
            |-- data.sql
            `-- schema.sql

build.gradle

org.mybatis.spring.boot:mybatis-spring-boot-starter のバージョンは spring-boot-gradle-plugin によって自動解決されないため、こちらのページをもとに調べて指定する必要があります。今回は 1.3.0 を利用します。

buildscript {
    ext {
        springBootVersion = '1.5.3.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

jar {
    baseName = 'gs-spring-boot'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')

    compile('mysql:mysql-connector-java:6.0.6')

    // 以下のページをもとにバージョンを指定します。
    // http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/
    // http://search.maven.org/#artifactdetails|org.mybatis.spring.boot|mybatis-spring-boot-starter|1.3.0|jar
    compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.0')
}

src/main/resources/application.yml

MySQL DB 接続情報を設定します。

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: myuser
    password: myuser
    driver-class-name: com.mysql.jdbc.Driver

src/main/resources/{schema|data}.sql

出力先 MySQL テーブルの DDL および DML です。こちらのページに記載されているとおり、schema.sql および data.sql というファイル名の SQL がアプリケーション起動時に実行されます。より柔軟かつ高度な初期化処理が必要な場合は Flyway と連携するように設定します

schema.sql

DROP TABLE IF EXISTS city;
CREATE TABLE city (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255),
    state VARCHAR(255),
    country VARCHAR(255)
);

data.sql

INSERT INTO city (name, state, country) VALUES ('San Francisco', 'CA', 'US');

src/main/java/hello/Application.java

アノテーションの意味については、こちらをご参照ください。

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

src/main/java/hello/City.java

Getter/Setter が定義されたドメインクラスです。Lombok@Data などを利用すると簡潔な記述が可能になりますが、今回は使用していません。

package hello;

public class City {

    private Long id;
    private String name;
    private String state;
    private String country;

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getState() {
        return this.state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getCountry() {
        return this.country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    public String toString() {
        return getId() + "," + getName() + "," + getState() + "," + getCountry();
    }
}

src/main/java/hello/CityMapper.java

@Param アノテーションは、今回のようにパラメータが一つの場合は指定しなくても問題ありませんが、複数パラメータが存在する場合は SQL クエリ内のパラメータとメソッド引数の対応関係を設定するために指定する必要があります。また、ここでは @Select アノテーションで SQL を設定していますが、より柔軟な設定を行うためには後述の XML ファイルを利用します。

package hello;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface CityMapper {
    @Select("SELECT id, name, state, country FROM city WHERE state = #{state}")
    City findByState(@Param("state") String state);
}

src/main/java/hello/HelloController.java

cityMapper.findByState() および sqlSession.selectOne() を利用する例です。実際にはコントローラ内で直接利用するのではなく@Service や @Repository を設定したクラス内で利用します。

package hello;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @Autowired
    private CityMapper cityMapper;

    @Autowired
    private SqlSession sqlSession;

    @RequestMapping("/")
    public String index() {
        City city1 = cityMapper.findByState("CA");
        City city2 = sqlSession.selectOne("hello.CityMapper.findByState", "CA");
        System.out.println(city1);
        System.out.println(city2);
        return "Greetings from Spring Boot!";
    }
}

XML による SQL 設定

サンプルプロジェクトにおいて、アノテーションで設定していた箇所を XML ファイルに置き換えると以下のようになります。

src/main/java/hello/CityMapper.java

package hello;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
//import org.apache.ibatis.annotations.Select;

@Mapper
public interface CityMapper {
    // @Select("SELECT id, name, state, country FROM city WHERE state = #{state}")
    City findByState(@Param("state") String state);
}

src/main/resources/hello/CityMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="hello.CityMapper">
  <select id="findByState" resultType="hello.City">
    SELECT * FROM city WHERE state = #{state}
  </select>
</mapper>

SQL 設定のサンプル集

凡例

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="hello.CityMapper">

  [[SQL 設定がここに入ります]]

</mapper>

適宜 @Param 設定を設定してください。返り値も適宜 List<City> に変更してください。

package hello;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface CityMapper {
    City findByState(@Param("name") String name, @Param("state") String state);
}

動的 SQL

if

<select id="findByState" resultType="hello.City">
  SELECT * FROM city WHERE name LIKE #{name}
  <if test="state != null">
    AND state = #{state}
  </if>
</select>

choose

いずれか一つだけ選択されます。switch-case 文のようなものです。

<select id="findByState" resultType="hello.City">
  SELECT * FROM city WHERE
  <choose>
    <when test="name != null">
      name = #{name}
    </when>
    <when test="state != null">
      state = #{state}
    </when>
    <otherwise>
      country = 'mycountry'
    </otherwise>
  </choose>
</select>

where

where を利用すると、条件に一つも合致しない場合は何も挿入されず、合致した最初の条件が AND や OR から始まる場合は取り除かれます。以下の例で name も state も指定しないと city が全件返されます。state だけ指定すると AND が削除されて WHERE 句が挿入されます。

<select id="findByState" resultType="hello.City">
  SELECT * FROM city
  <where>
    <if test="name != null">
      name = #{name}
    </if>
    <if test="state != null">
      AND state = #{state}
    </if>
  </where>
</select>

trim

where のような機能をカスタマイズして実現したい場合は trim を利用します。where のサンプルコードを trim で記述すると以下のようになります。

<select id="findByState" resultType="hello.City">
  SELECT * FROM city
  <trim prefix="WHERE" prefixOverrides="AND |OR ">
    <if test="name != null">
      name = #{name}
    </if>
    <if test="state != null">
      AND state = #{state}
    </if>
  </trim>
</select>

set

UPDATE 文について、set を利用すると合致した最後の条件が , で終わる場合は取り除かれます。where の場合と同様に trim で同等の機能を実現できます。

<update id="findByState">
  UPDATE city
  <set>
    <if test="name != null">name=#{name},</if>
    <if test="state != null">state=#{state}</if>
  </set>
  WHERE country = 'US'
</update>

foreach

<select id="findByState" resultType="hello.City">
  SELECT * FROM city WHERE name IN
  <foreach item="name" index="index" collection="names" open="(" separator="," close=")">
    #{name}
  </foreach>
</select>

bind

一時変数を定義できます。引数も参照できます。

<select id="findByState" resultType="hello.City">
  <bind name="pattern" value="'%' + name + '%'" />
  SELECT * FROM city WHERE name LIKE #{pattern}
</select>

静的 SQL

select

ここまでのサンプルで利用してきた、独自に定義した City 以外にも、基本的な resultType が予め用意されています。例えば hashmap を利用すると以下のようになります。

この続きが気になる方は

Spring Boot から MyBatis を利用するための設定 (Gradle/MySQL)

残り文字数は全体の約 53 %
なつかしのねこ
100 円
関連ページ
    概要 Spring フレームワークにおける @Transactional アノテーションを利用すると DB トランザクション処理が簡単に設定できます。ここでは特に、こちらのページで環境構築した Spring Boot から MyBatis を経由して MySQL を利用する場合を対象としますが、JDBC を利用して他の DB を操作する場合も考え方は同じです。