Spring5 MyBatisのトランザクションのサンプル

Spring5のMyBatisでデータ更新時のトランザクションのサンプルです。

(確認環境:Spring 5.3.7,JDK 11,STS 4,MySQL)

目次

サンプル Spring5のMyBatisのトランザクションのサンプル
  1.起動するファイル(MainController.java)
  2.設定ファイル(applicationContext.xml)
  3.GetDataService.java
  4.SyainRepository.java
  5.sql.xml (update/insert)
  実行する

Spring5とMyBatisでselectする概要

今回作成したファイルです。

MainController.javaから起動し
applicationContext.xmlを読み込みGetDataService.javaのメソッドを実行します。
最初にupdateを実行し、次にinsertを実行しますが重複キーでロールバックされるシナリオです。
sql.xmlにupdate文とinsert文があります。

githubにコードがあります。
https://github.com/ut23405/spring5db/tree/master/spring5-mybatis-transaction

1.起動するファイル(MainController.java)

package com.example.test1;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;

@Controller
public class MainController {
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext  context =
			new ClassPathXmlApplicationContext("applicationContext.xml");

		GetDataService gdservice = (GetDataService) context.getBean("GetData");
		
		try {
			gdservice.TransactionTest();
		} catch(DuplicateKeyException e) {
		    System.out.println(e.getMessage());
		}catch(Exception e) {
			System.out.println(e.getMessage());
		}
		context.close();
	}
}

applicationContext.xmlから対象のクラスをDIコンテナにbeanとして登録します。
context.getBeanでbean(インスタンス)を取得してメソッドを実行します。
17行目は、メソッドの呼び出し先でupdateとinsertを行います。
18行目は、重複キーのエラーだった場合にキャッチします。

2.設定ファイル(applicationContext.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">

	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName"
			value="com.mysql.cj.jdbc.Driver" />
		<property name="url"
			value="jdbc:mysql://localhost:3309/testphp" />
		<property name="username" value="root" />
		<property name="password" value="" />
	</bean>
	<bean id="sqlSessionFactory"
		class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="mapperLocations" value="sql.xml" />
	</bean>
	<bean id="SyainRepository"
		class="org.mybatis.spring.mapper.MapperFactoryBean">
		<property name="mapperInterface"
			value="com.example.test1.SyainRepository" />
		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
	</bean>
	<bean id="GetData" class="com.example.test1.GetDataService">
		<constructor-arg ref="SyainRepository" />
	</bean>
	
	<tx:annotation-driven />
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
        <property name="rollbackOnCommitFailure" value="true" />
    </bean>
</beans>

11~19行目は、MySQLの接続情報です。idはdataSourceです。
22,38行目のref="dataSource"とひも付きます。
20行目のSqlSessionFactoryBeanはMyBatisとSpringを組み合わせて使う場合必須です。
23行目は、sqlファイル(sql.xml)を指定しています。
28行目のMapperFactoryBeanで指定するMapper(SyainRepository)はインターフェースです。
このインターフェースを実装するクラスのインスタンスはMyBatisが自動で生成します。
31,32行目は、コンストラクタです。SyainRepositoryは引数です。
35,36行目は、トランザクション制御をするときに必要です。5,8,9行目のtxのxmlも必要です。

3.GetDataService.java

package com.example.test1;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class GetDataService {
	private final SyainRepository sr1;

	public GetDataService(SyainRepository sr1) {
		this.sr1 = sr1;
	}

//	@Transactional(rollbackFor = Exception.class)
	@Transactional
	public void TransactionTest() {
		sr1.update1();
		sr1.insert1();
	}
}

15行目は、Transactionalアノテーションです。トランザクション制御に必要です。
17,18行目は、最初にupdateを行い次にinsertを行います。
insertで重複キーエラーが発生した場合は、updateの更新がロールバックされるか確認します。
14行目のコメントを外すと検査例外(Exceptionのエラー)での失敗時もロールバックします。

5.SyainRepository.java

package com.example.test1;


import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface SyainRepository {
	public void insert1();
	public void update1();
}

インターフェースです。

6.sql.xml (update/insert)

<?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="com.example.test1.SyainRepository">
	<select id="insert1" >
		INSERT INTO syain(id,name,romaji) VALUES (19,'山下','yamashita')
	</select>
	<select id="update1" >
		UPDATE syain
		SET name = '竹田', romaji = 'takeda'
		WHERE id = 2;
	</select>
</mapper>

insert文とupdate文です。

実行する

insert文が成功したときは、updateの更新もコミットされます。
insert文が失敗したときは、updateの更新はロールバックされます。

コードの中にcommitやrollbackを書く必要はありません。

以下は、MyBatisのスタートガイドのリンクです。
https://mybatis.org/spring/ja/getting-started.html

関連の記事

Spring5 MyBatisでselectするサンプル(XML)

△上に戻る