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 テーブルの中身と一致しているので問題ありません。
コメント