MyBatisでUUIDを使用する方法

Java

MyBatis は標準で UUID をサポートしていないようなので、BaseTypeHandler クラスを継承した独自の UUIDTypeHandler クラスを作成して対応します。

UUIDTypeHandler の実装

package com.example.mybatis.typehandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

@MappedJdbcTypes(JdbcType.OTHER)
@MappedTypes(UUID.class)
public class UUIDTypeHandler extends BaseTypeHandler<UUID> {

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, UUID parameter, JdbcType jdbcType)
			throws SQLException {
		ps.setObject(i, parameter);
	}

	@Override
	public UUID getNullableResult(ResultSet rs, String columnName) throws SQLException {
		return rs.getObject(columnName, UUID.class);
	}

	@Override
	public UUID getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		return rs.getObject(columnIndex, UUID.class);
	}

	@Override
	public UUID getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		return cs.getObject(columnIndex, UUID.class);
	}
}

application.yaml の設定

application.yaml で mybatis.type-handlers-package に UUIDTypeHandler のパッケージ(com.example.mybatis.typehandler)を設定すると自動的に適用されました。

# application.yaml
spring:
  datasource:
    url: jdbc:h2:mem:test;DATABASE_TO_UPPER=false;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
    username: sa

mybatis:
  type-handlers-package: com.example.mybatis.typehandler

その他のファイル

プロジェクトの構成は次の通りです。

Application クラスで動作確認をするため、起動時に UUID をSELECTしてログ出力しています。

package com.example;

import java.util.List;
import java.util.UUID;

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

import com.example.mybatis.UserMapper;

import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@SpringBootApplication
@RequiredArgsConstructor
@Slf4j
public class Application {

	private final UserMapper mapper;

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

	@PostConstruct
	public void exec() {
		List<UUID> userIds = mapper.selectUserIds();
		log.info("{}", userIds);
	}
}

MyBatis で users テーブルの id をSELECTします。

package com.example.mybatis;

import java.util.List;
import java.util.UUID;

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

@Mapper
public interface UserMapper {

	@Select("SELECT id FROM users")
	List<UUID> selectUserIds();
}

スキーマ定義

-- schema.sql
DROP ALIAS IF EXISTS gen_random_uuid;
CREATE ALIAS gen_random_uuid AS '
import java.util.UUID;
@CODE
java.util.UUID genRandomUuid() throws Exception {
	return UUID.randomUUID();
}
';

DROP TABLE if exists "users" CASCADE;
CREATE TABLE "users" (
  "id" uuid DEFAULT gen_random_uuid() NOT NULL
  , "name" text NOT NULL
  , CONSTRAINT "users_PKC" PRIMARY KEY ("id")
) ;

データ作成

-- data.sql
INSERT INTO users(name) VALUES 
    ('aaa')
  , ('bbb')
  , ('ccc');

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.0.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>sample-mybatis-uuid</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>sample-mybatis-uuid</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>3.0.0</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter-test</artifactId>
			<version>3.0.0</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

アプリケーションを起動すると下記の UUID がログ出力されました。

[2b15a47e-fedb-439c-9de1-dc1feed7cec3, 36fb3c40-6c3e-4ee3-a4b3-5dcd95b771c2, e8f13db7-4b3b-4c1b-92ff-deba2bf1a1d1]

users テーブルの中身と一致しているので問題ありません。

users table

コメント

タイトルとURLをコピーしました