truncate table文によって、テーブルの全データを削除することができるが、truncate table文を実行した後でロールバックできるかどうかは、DBの種類によって異なる。
今回は、JUnit5 DBUnitを利用して、truncate table文を実行した時の動きを確認してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
やってみたこと
- 作成したサンプルプログラムの構成
- Oracleの場合のソースコードとテスト実行結果
- MySQLの場合のソースコードとテスト実行結果
- PostgreSQLの場合のソースコードとテスト実行結果
- SQL Serverの場合のソースコードとテスト実行結果
作成したサンプルプログラムの構成
作成したサンプルプログラムの構成は以下の通り。

なお、上記の赤枠は、このブログで掲載するソースコードを示す。
test.propertiesの内容は以下の通りで、JUnit5 DBUnitで利用する各DBの接続先を示していて、各DBの接続定義となるDemoTest~Configクラスで参照している。
# DB接続先(Oracle) spring.datasourceut-ora.url=jdbc:oracle:thin:@localhost:1521:xe spring.datasourceut-ora.username=USER01 spring.datasourceut-ora.password=USER01 spring.datasourceut-ora.driverClassName=oracle.jdbc.driver.OracleDriver # DB接続先(MySQL) spring.datasourceut-ms.url=jdbc:mysql://localhost:3306/user01?serverTimezone=JST spring.datasourceut-ms.username=USER01 spring.datasourceut-ms.password=USER01 spring.datasourceut-ms.driverClassName=com.mysql.cj.jdbc.Driver # DB接続情報(PostgreSQL) spring.datasourceut-ps.url=jdbc:postgresql://localhost:5432/USER01 spring.datasourceut-ps.username=USER01 spring.datasourceut-ps.password=USER01 spring.datasourceut-ps.driverClassName=org.postgresql.Driver # DB接続先(SQLServer) spring.datasourceut-ss.url=jdbc:sqlserver://localhost:1433;databaseName=master spring.datasourceut-ss.username=USER01 spring.datasourceut-ss.password=USER01 spring.datasourceut-ss.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
また、上記赤枠以外のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/junit5-dbunit-truncate-table/demo
Oracleの場合のソースコードとテスト実行結果
テスト対象となるMapperの内容は、以下の通り。
package com.example.demo.mapper.ora;
import com.example.demo.mapper.UserData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDataMapperOra {
/**
* Oracleでユーザーデータテーブル(user_data)の全データを取得する
* @return ユーザーデータテーブル(user_data)の全データ
*/
List<UserData> findAll();
/**
* Oracleでユーザーデータテーブル(user_data)の全データを削除する
*/
void truncateUserData();
}<?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.demo.mapper.ora.UserDataMapperOra">
<resultMap id="userDataResultMap" type="com.example.demo.mapper.UserData" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="birthY" property="birthY" jdbcType="VARCHAR" />
<result column="birthM" property="birthM" jdbcType="VARCHAR" />
<result column="birthD" property="birthD" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="memo" property="memo" jdbcType="VARCHAR" />
<result column="sex_value" property="sex_value" jdbcType="VARCHAR" />
</resultMap>
<select id="findAll" resultMap="userDataResultMap">
SELECT
id
, name
, birth_year as birthY
, birth_month as birthM
, birth_day as birthD
, sex
, memo
, CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE ''
END AS sex_value
FROM USER_DATA
</select>
<update id="truncateUserData">
TRUNCATE TABLE USER_DATA
</update>
</mapper>また、JUnit5 DBUnitで利用するDB接続先設定の内容は、以下の通り。
package com.example.demo.mapper.ora;
import com.github.springtestdbunit.bean.DatabaseConfigBean;
import com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean;
import org.dbunit.ext.oracle.Oracle10DataTypeFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
// MyBatisのテストを実行する際のDB接続定義
// @MybatisTestアノテーションでテストを実行する際、
// Spring Bootアプリケーションが起動するようにする。
// その際、com.example.demo.mapper.oraフォルダ下のインスタンス
// (UserDataMapper)のみがDIで使用できるようになる。
@SpringBootApplication
@PropertySource(value = {"classpath:test.properties"})
public class DemoTestOraConfig {
/**
* Oracleのデータソースプロパティ(UT)を生成する.
* @return Oracleのデータソースプロパティ(UT)
*/
@Bean(name = {"datasourceOraProperties"})
@Primary
@ConfigurationProperties(prefix = "spring.datasourceut-ora")
public DataSourceProperties datasourceOraProperties() {
return new DataSourceProperties();
}
/**
* Oracleのデータソース(UT)を生成する.
* @param properties Oracleのデータソースプロパティ(UT)
* @return Oracleのデータソース(UT)
*/
@Bean(name = {"dataSourceOra"})
@Primary
public DataSource datasourceOra(
@Qualifier("datasourceOraProperties") DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
/**
* Oracleのトランザクションマネージャ(UT)を生成する.
* @param dataSourceOra Oracleのデータソース(UT)
* @return Oracleのトランザクションマネージャ(UT)
*/
@Bean(name = {"txManagerOra"})
@Primary
public PlatformTransactionManager txManagerOra(
@Qualifier("dataSourceOra") DataSource dataSourceOra) {
return new DataSourceTransactionManager(dataSourceOra);
}
/**
* OracleのDB接続設定(UT)を生成する.
* @return OracleのDB接続設定(UT)
*/
@Bean(name = {"dbUnitDatabaseConfigOra"})
public DatabaseConfigBean dbUnitDatabaseConfigOra() {
DatabaseConfigBean bean = new DatabaseConfigBean();
bean.setAllowEmptyFields(true);
bean.setDatatypeFactory(new Oracle10DataTypeFactory());
return bean;
}
/**
* Oracleのデータソースコネクションファクトリ(UT)を生成する.
* @param dbUnitDatabaseConfigOra OracleのDB接続設定(UT)
* @param dataSourceOra Oracleのデータソース(UT)
* @return Oracleのデータソースコネクションファクトリ(UT)
*/
@Bean(name = {"dbUnitDatabaseConnectionOra"})
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnectionOra(
@Qualifier("dbUnitDatabaseConfigOra") DatabaseConfigBean dbUnitDatabaseConfigOra,
@Qualifier("dataSourceOra") DataSource dataSourceOra) {
DatabaseDataSourceConnectionFactoryBean bean
= new DatabaseDataSourceConnectionFactoryBean(dataSourceOra);
bean.setDatabaseConfig(dbUnitDatabaseConfigOra);
bean.setSchema("USER01");
return bean;
}
}さらに、Mapperのテストクラスの内容は以下の通りで、truncate table文とその実行前後のデータを取得している。
package com.example.demo.mapper.ora;
import com.example.demo.mapper.DemoXlsDataSetLoader;
import com.example.demo.mapper.UserData;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import java.util.List;
import static org.junit.Assert.assertEquals;
// JUnit5ベースでMyBatisのテストを実行する
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class
, DirtiesContextTestExecutionListener.class
, TransactionDbUnitTestExecutionListener.class
, DbUnitTestExecutionListener.class})
@DbUnitConfiguration(dataSetLoader = DemoXlsDataSetLoader.class
, databaseConnection = {"dbUnitDatabaseConnectionOra"})
public class UserDataTruncateTestOra {
/**
* ユーザーデータテーブル(user_data)へアクセスするマッパー
*/
@Autowired
private UserDataMapperOra userDataMapperOra;
/**
* 各テストメソッドを実行する前に行う処理を定義する.
*/
@BeforeEach
public void beforeTest() {
System.out.println();
System.out.println("*** UserDataTruncateTestOraクラス テスト結果 start ***");
}
/**
* truncate文の実行結果を検証する.
*/
@Test
public void userDataTest() {
// ユーザーデータ削除する前のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ Truncate前 ***");
List<UserData> userDataList = userDataMapperOra.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
// ユーザーデータを削除
userDataMapperOra.truncateUserData();
// ユーザーデータ削除した後のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ Truncate後 ***");
userDataList = userDataMapperOra.findAll();
System.out.println(userDataList);
assertEquals(0, userDataList.size());
}
/**
* 各テストメソッドを実行した後に行う処理を定義する.
*/
@AfterEach
public void afterTestClass() {
System.out.println("*** UserDataTruncateTestOraクラス テスト結果 end ***");
System.out.println();
}
}上記テストクラスの実行結果は以下の通りで、truncate table文の実行でコミットされていることが確認できる。
MySQLの場合のソースコードとテスト実行結果
テスト対象となるMapperの内容は、以下の通り。
package com.example.demo.mapper.ms;
import com.example.demo.mapper.UserData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDataMapperMs {
/**
* MySQLでユーザーデータテーブル(user_data)の全データを取得する
* @return ユーザーデータテーブル(user_data)の全データ
*/
List<UserData> findAll();
/**
* MySQLでユーザーデータテーブル(user_data)の全データを削除する
*/
void truncateUserData();
}<?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.demo.mapper.ms.UserDataMapperMs">
<resultMap id="userDataResultMap" type="com.example.demo.mapper.UserData" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="birthY" property="birthY" jdbcType="VARCHAR" />
<result column="birthM" property="birthM" jdbcType="VARCHAR" />
<result column="birthD" property="birthD" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="memo" property="memo" jdbcType="VARCHAR" />
<result column="sex_value" property="sex_value" jdbcType="VARCHAR" />
</resultMap>
<select id="findAll" resultMap="userDataResultMap">
SELECT
id
, name
, birth_year as birthY
, birth_month as birthM
, birth_day as birthD
, sex
, memo
, CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE ''
END AS sex_value
FROM USER_DATA
</select>
<update id="truncateUserData">
TRUNCATE TABLE USER_DATA
</update>
</mapper>また、JUnit5 DBUnitで利用するDB接続先設定の内容は、以下の通り。
package com.example.demo.mapper.ms;
import com.github.springtestdbunit.bean.DatabaseConfigBean;
import com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean;
import org.dbunit.ext.mysql.MySqlDataTypeFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
// MyBatisのテストを実行する際のDB接続定義
// @MybatisTestアノテーションでテストを実行する際、
// Spring Bootアプリケーションが起動するようにする。
// その際、com.example.demo.mapper.msフォルダ下のインスタンス
// (UserDataMapper)のみがDIで使用できるようになる。
@SpringBootApplication
@PropertySource(value = {"classpath:test.properties"})
public class DemoTestMsConfig {
/**
* MySQLのデータソースプロパティ(UT)を生成する.
* @return MySQLのデータソースプロパティ(UT)
*/
@Bean(name = {"datasourceMsProperties"})
@Primary
@ConfigurationProperties(prefix = "spring.datasourceut-ms")
public DataSourceProperties datasourceMsProperties() {
return new DataSourceProperties();
}
/**
* MySQLのデータソース(UT)を生成する.
* @param properties MySQLのデータソースプロパティ(UT)
* @return MySQLのデータソース(UT)
*/
@Bean(name = {"dataSourceMs"})
@Primary
public DataSource datasourceMs(
@Qualifier("datasourceMsProperties") DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
/**
* MySQLのトランザクションマネージャ(UT)を生成する.
* @param dataSourceMs MySQLのデータソース(UT)
* @return MySQLのトランザクションマネージャ(UT)
*/
@Bean(name = {"txManagerMs"})
@Primary
public PlatformTransactionManager txManagerMs(
@Qualifier("dataSourceMs") DataSource dataSourceMs) {
return new DataSourceTransactionManager(dataSourceMs);
}
/**
* MySQLのDB接続設定(UT)を生成する.
* @return MySQLのDB接続設定(UT)
*/
@Bean(name = {"dbUnitDatabaseConfigMs"})
public DatabaseConfigBean dbUnitDatabaseConfigMs() {
DatabaseConfigBean bean = new DatabaseConfigBean();
bean.setAllowEmptyFields(true);
bean.setDatatypeFactory(new MySqlDataTypeFactory());
return bean;
}
/**
* MySQLのデータソースコネクションファクトリ(UT)を生成する.
* @param dbUnitDatabaseConfigMs MySQLのDB接続設定(UT)
* @param dataSourceMs MySQLのデータソース(UT)
* @return MySQLのデータソースコネクションファクトリ(UT)
*/
@Bean(name = {"dbUnitDatabaseConnectionMs"})
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnectionOra(
@Qualifier("dbUnitDatabaseConfigMs") DatabaseConfigBean dbUnitDatabaseConfigMs,
@Qualifier("dataSourceMs") DataSource dataSourceMs) {
DatabaseDataSourceConnectionFactoryBean bean
= new DatabaseDataSourceConnectionFactoryBean(dataSourceMs);
bean.setDatabaseConfig(dbUnitDatabaseConfigMs);
return bean;
}
}さらに、Mapperのテストクラスの内容は以下の通りで、truncate table文とその実行前後のデータを取得している。
package com.example.demo.mapper.ms;
import com.example.demo.mapper.DemoXlsDataSetLoader;
import com.example.demo.mapper.UserData;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import java.util.List;
import static org.junit.Assert.assertEquals;
// JUnit5ベースでMyBatisのテストを実行する
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class
, DirtiesContextTestExecutionListener.class
, TransactionDbUnitTestExecutionListener.class
, DbUnitTestExecutionListener.class})
@DbUnitConfiguration(dataSetLoader = DemoXlsDataSetLoader.class
, databaseConnection = {"dbUnitDatabaseConnectionMs"})
public class UserDataTruncateTestMs {
/**
* ユーザーデータテーブル(user_data)へアクセスするマッパー
*/
@Autowired
private UserDataMapperMs userDataMapperMs;
/**
* 各テストメソッドを実行する前に行う処理を定義する.
*/
@BeforeEach
public void beforeTest() {
System.out.println();
System.out.println("*** UserDataTruncateTestMsクラス テスト結果 start ***");
}
/**
* truncate文の実行結果を検証する.
*/
@Test
public void userDataTest() {
// ユーザーデータ削除する前のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ Truncate前 ***");
List<UserData> userDataList = userDataMapperMs.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
System.out.println();
// ユーザーデータを削除
userDataMapperMs.truncateUserData();
// ユーザーデータ削除した後のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ Truncate後 ***");
userDataList = userDataMapperMs.findAll();
System.out.println(userDataList);
assertEquals(0, userDataList.size());
}
/**
* 各テストメソッドを実行した後に行う処理を定義する.
*/
@AfterEach
public void afterTestClass() {
System.out.println("*** UserDataTruncateTestMsクラス テスト結果 end ***");
System.out.println();
}
}上記テストクラスの実行結果は以下の通りで、truncate table文の実行でコミットされていることが確認できる。
PostgreSQLの場合のソースコードとテスト実行結果
テスト対象となるMapperの内容は、以下の通り。
package com.example.demo.mapper.ps;
import com.example.demo.mapper.UserData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDataMapperPs {
/**
* PostgreSQLでユーザーデータテーブル(user_data)の全データを取得する
* @return ユーザーデータテーブル(user_data)の全データ
*/
List<UserData> findAll();
/**
* PostgreSQLでユーザーデータテーブル(user_data)の全データを削除する
*/
void truncateUserData();
}<?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.demo.mapper.ps.UserDataMapperPs">
<resultMap id="userDataResultMap" type="com.example.demo.mapper.UserData" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="birthY" property="birthY" jdbcType="VARCHAR" />
<result column="birthM" property="birthM" jdbcType="VARCHAR" />
<result column="birthD" property="birthD" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="memo" property="memo" jdbcType="VARCHAR" />
<result column="sex_value" property="sex_value" jdbcType="VARCHAR" />
</resultMap>
<select id="findAll" resultMap="userDataResultMap">
SELECT
id
, name
, birth_year as birthY
, birth_month as birthM
, birth_day as birthD
, sex
, memo
, CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE ''
END AS sex_value
FROM USER_DATA
</select>
<update id="truncateUserData">
TRUNCATE TABLE USER_DATA
</update>
</mapper>また、JUnit5 DBUnitで利用するDB接続先設定の内容は、以下の通り。
package com.example.demo.mapper.ps;
import com.github.springtestdbunit.bean.DatabaseConfigBean;
import com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean;
import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
// MyBatisのテストを実行する際のDB接続定義
// @MybatisTestアノテーションでテストを実行する際、
// Spring Bootアプリケーションが起動するようにする。
// その際、com.example.demo.mapper.oraフォルダ下のインスタンス
// (UserDataMapper)のみがDIで使用できるようになる。
@SpringBootApplication
@PropertySource(value = {"classpath:test.properties"})
public class DemoTestPsConfig {
/**
* PostgreSQLのデータソースプロパティ(UT)を生成する.
* @return PostgreSQLのデータソースプロパティ(UT)
*/
@Bean(name = {"datasourcePsProperties"})
@Primary
@ConfigurationProperties(prefix = "spring.datasourceut-ps")
public DataSourceProperties datasourcePsProperties() {
return new DataSourceProperties();
}
/**
* PostgreSQLのデータソース(UT)を生成する.
* @param properties PostgreSQLのデータソースプロパティ(UT)
* @return PostgreSQLのデータソース(UT)
*/
@Bean(name = {"dataSourcePs"})
@Primary
public DataSource datasourcePs(
@Qualifier("datasourcePsProperties") DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
/**
* PostgreSQLのトランザクションマネージャ(UT)を生成する.
* @param dataSourcePs PostgreSQLのデータソース(UT)
* @return PostgreSQLのトランザクションマネージャ(UT)
*/
@Bean(name = {"txManagerPs"})
@Primary
public PlatformTransactionManager txManagerPs(
@Qualifier("dataSourcePs") DataSource dataSourcePs) {
return new DataSourceTransactionManager(dataSourcePs);
}
/**
* PostgreSQLのDB接続設定(UT)を生成する.
* @return PostgreSQLのDB接続設定(UT)
*/
@Bean(name = {"dbUnitDatabaseConfigPs"})
public DatabaseConfigBean dbUnitDatabaseConfigPs() {
DatabaseConfigBean bean = new DatabaseConfigBean();
bean.setAllowEmptyFields(true);
bean.setDatatypeFactory(new PostgresqlDataTypeFactory());
return bean;
}
/**
* PostgreSQLのデータソースコネクションファクトリ(UT)を生成する.
* @param dbUnitDatabaseConfigPs PostgreSQLのDB接続設定(UT)
* @param dataSourcePs PostgreSQLのデータソース(UT)
* @return PostgreSQLのデータソースコネクションファクトリ(UT)
*/
@Bean(name = {"dbUnitDatabaseConnectionPs"})
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnectionPs(
@Qualifier("dbUnitDatabaseConfigPs") DatabaseConfigBean dbUnitDatabaseConfigPs,
@Qualifier("dataSourcePs") DataSource dataSourcePs) {
DatabaseDataSourceConnectionFactoryBean bean
= new DatabaseDataSourceConnectionFactoryBean(dataSourcePs);
bean.setDatabaseConfig(dbUnitDatabaseConfigPs);
return bean;
}
}さらに、Mapperのテストクラスの内容は以下の通りで、truncate table文とその実行前後のデータを取得している。
package com.example.demo.mapper.ps;
import com.example.demo.mapper.DemoXlsDataSetLoader;
import com.example.demo.mapper.UserData;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import java.util.List;
import static org.junit.Assert.assertEquals;
// JUnit5ベースでMyBatisのテストを実行する
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class
, DirtiesContextTestExecutionListener.class
, TransactionDbUnitTestExecutionListener.class
, DbUnitTestExecutionListener.class})
@DbUnitConfiguration(dataSetLoader = DemoXlsDataSetLoader.class
, databaseConnection = {"dbUnitDatabaseConnectionPs"})
public class UserDataTruncateTestPs {
/**
* ユーザーデータテーブル(user_data)へアクセスするマッパー
*/
@Autowired
private UserDataMapperPs userDataMapperPs;
/**
* 各テストメソッドを実行する前に行う処理を定義する.
*/
@BeforeEach
public void beforeTest() {
System.out.println();
System.out.println("*** UserDataTruncateTestPsクラス テスト結果 start ***");
}
/**
* truncate文の実行結果を検証する.
*/
@Test
public void userDataTest() {
// ユーザーデータ削除する前のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ Truncate前 ***");
List<UserData> userDataList = userDataMapperPs.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
// ユーザーデータを削除
userDataMapperPs.truncateUserData();
// ユーザーデータ削除した後のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ Truncate後 ***");
userDataList = userDataMapperPs.findAll();
System.out.println(userDataList);
assertEquals(0, userDataList.size());
}
/**
* 各テストメソッドを実行した後に行う処理を定義する.
*/
@AfterEach
public void afterTestClass() {
System.out.println("*** UserDataTruncateTestPsクラス テスト結果 end ***");
System.out.println();
}
}上記テストクラスの実行結果は以下の通りで、truncate table文の実行でロールバックされていることが確認できる。
SQL Serverの場合のソースコードとテスト実行結果
テスト対象となるMapperの内容は、以下の通り。
package com.example.demo.mapper.ss;
import com.example.demo.mapper.UserData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDataMapperSs {
/**
* SQL Serverでユーザーデータテーブル(user_data)の全データを取得する
* @return ユーザーデータテーブル(user_data)の全データ
*/
List<UserData> findAll();
/**
* SQL Serverでユーザーデータテーブル(user_data)の全データを削除する
*/
void truncateUserData();
}<?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.demo.mapper.ss.UserDataMapperSs">
<resultMap id="userDataResultMap" type="com.example.demo.mapper.UserData" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="birthY" property="birthY" jdbcType="VARCHAR" />
<result column="birthM" property="birthM" jdbcType="VARCHAR" />
<result column="birthD" property="birthD" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="memo" property="memo" jdbcType="VARCHAR" />
<result column="sex_value" property="sex_value" jdbcType="VARCHAR" />
</resultMap>
<select id="findAll" resultMap="userDataResultMap">
SELECT
id
, name
, birth_year as birthY
, birth_month as birthM
, birth_day as birthD
, sex
, memo
, CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE ''
END AS sex_value
FROM dbo.USER_DATA
</select>
<update id="truncateUserData">
TRUNCATE TABLE dbo.USER_DATA
</update>
</mapper>また、JUnit5 DBUnitで利用するDB接続先設定の内容は、以下の通り。
package com.example.demo.mapper.ss;
import com.github.springtestdbunit.bean.DatabaseConfigBean;
import com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean;
import org.dbunit.ext.mssql.MsSqlDataTypeFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
// MyBatisのテストを実行する際のDB接続定義
// @MybatisTestアノテーションでテストを実行する際、
// Spring Bootアプリケーションが起動するようにする。
// その際、com.example.demo.mapper.oraフォルダ下のインスタンス
// (UserDataMapper)のみがDIで使用できるようになる。
@SpringBootApplication
@PropertySource(value = {"classpath:test.properties"})
public class DemoTestSsConfig {
/**
* SQLServerのデータソースプロパティ(UT)を生成する.
* @return SQLServerのデータソースプロパティ(UT)
*/
@Bean(name = {"datasourceSsProperties"})
@Primary
@ConfigurationProperties(prefix = "spring.datasourceut-ss")
public DataSourceProperties datasourceSsProperties() {
return new DataSourceProperties();
}
/**
* SQLServerのデータソース(UT)を生成する.
* @param properties SQLServerのデータソースプロパティ(UT)
* @return SQLServerのデータソース(UT)
*/
@Bean(name = {"dataSourceSs"})
@Primary
public DataSource datasourceSs(
@Qualifier("datasourceSsProperties") DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
/**
* SQLServerのトランザクションマネージャ(UT)を生成する.
* @param dataSourceSs SQLServerのデータソース(UT)
* @return SQLServerのトランザクションマネージャ(UT)
*/
@Bean(name = {"txManagerSs"})
@Primary
public PlatformTransactionManager txManagerSs(
@Qualifier("dataSourceSs") DataSource dataSourceSs) {
return new DataSourceTransactionManager(dataSourceSs);
}
/**
* SQLServerのDB接続設定(UT)を生成する.
* @return SQLServerのDB接続設定(UT)
*/
@Bean(name = {"dbUnitDatabaseConfigSs"})
public DatabaseConfigBean dbUnitDatabaseConfigSs() {
DatabaseConfigBean bean = new DatabaseConfigBean();
bean.setAllowEmptyFields(true);
bean.setDatatypeFactory(new MsSqlDataTypeFactory());
return bean;
}
/**
* SQLServerのデータソースコネクションファクトリ(UT)を生成する.
* @param dbUnitDatabaseConfigSs SQLServerのDB接続設定(UT)
* @param dataSourceSs SQLServerのデータソース(UT)
* @return SQLServerのデータソースコネクションファクトリ(UT)
*/
@Bean(name = {"dbUnitDatabaseConnectionSs"})
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnectionSs(
@Qualifier("dbUnitDatabaseConfigSs") DatabaseConfigBean dbUnitDatabaseConfigSs,
@Qualifier("dataSourceSs") DataSource dataSourceSs) {
DatabaseDataSourceConnectionFactoryBean bean
= new DatabaseDataSourceConnectionFactoryBean(dataSourceSs);
bean.setDatabaseConfig(dbUnitDatabaseConfigSs);
return bean;
}
}さらに、Mapperのテストクラスの内容は以下の通りで、truncate table文とその実行前後のデータを取得している。
package com.example.demo.mapper.ss;
import com.example.demo.mapper.DemoXlsDataSetLoader;
import com.example.demo.mapper.UserData;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import java.util.List;
import static org.junit.Assert.assertEquals;
// JUnit5ベースでMyBatisのテストを実行する
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class
, DirtiesContextTestExecutionListener.class
, TransactionDbUnitTestExecutionListener.class
, DbUnitTestExecutionListener.class})
@DbUnitConfiguration(dataSetLoader = DemoXlsDataSetLoader.class
, databaseConnection = {"dbUnitDatabaseConnectionSs"})
public class UserDataTruncateTestSs {
/**
* ユーザーデータテーブル(user_data)へアクセスするマッパー
*/
@Autowired
private UserDataMapperSs userDataMapperSs;
/**
* 各テストメソッドを実行する前に行う処理を定義する.
*/
@BeforeEach
public void beforeTest() {
System.out.println();
System.out.println("*** UserDataTruncateTestSsクラス テスト結果 start ***");
}
/**
* truncate文の実行結果を検証する.
*/
@Test
public void userDataTest() {
// ユーザーデータ削除する前のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ Truncate前 ***");
List<UserData> userDataList = userDataMapperSs.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
// ユーザーデータを削除
userDataMapperSs.truncateUserData();
// ユーザーデータ削除した後のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ Truncate後 ***");
userDataList = userDataMapperSs.findAll();
System.out.println(userDataList);
assertEquals(0, userDataList.size());
}
/**
* 各テストメソッドを実行した後に行う処理を定義する.
*/
@AfterEach
public void afterTestClass() {
System.out.println("*** UserDataTruncateTestSsクラス テスト結果 end ***");
System.out.println();
}
}上記テストクラスの実行結果は以下の通りで、truncate table文の実行でロールバックされていることが確認できる。
要点まとめ
- JUnit5 DBUnitを利用して、truncate table文を実行すると、OracleとMySQLの場合はコミットされ、PostgreSQLとSQL Serverの場合はロールバックされることが確認できる。

















