You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让MyBatis忽略自带LocalDateTimeTypeHandler,使用自定义实现?

解决MyBatis 3.5.9自定义LocalDateTimeTypeHandler无法覆盖自带实现的问题

问题背景

使用Spring Boot集成MyBatis 3.5.9,POJO中LocalDateTime字段对应数据库TIMESTAMP类型,因MyBatis 3.4.1版本后自带的LocalDateTimeTypeHandler实现变更,触发"无法转换为TIMESTAMPZ"错误。复制旧版本逻辑自定义了LocalDateTimeTypeHandler,已通过mybatis.type-handlers-package配置扫描,调试时能命中自定义处理器断点,但最终仍调用MyBatis自带处理器。

解决方案

方法1:手动注册自定义处理器并排除自带实现

MyBatis默认优先加载自带类型处理器,需通过配置显式替换:

方式A:Java配置类实现

创建MyBatis配置类,手动移除自带处理器并注册自定义实现:

import org.apache.ibatis.session.Configuration;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import my.mapper.typehandlers.LocalDateTimeTypeHandler;
import java.time.LocalDateTime;
import org.apache.ibatis.type.JdbcType;

@Configuration
public class MyBatisConfig {
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> {
            // 移除MyBatis自带的LocalDateTime类型映射
            configuration.getTypeHandlerRegistry().unregister(LocalDateTime.class);
            configuration.getTypeHandlerRegistry().unregister(JdbcType.TIMESTAMP, LocalDateTime.class);
            // 注册自定义处理器
            configuration.getTypeHandlerRegistry().register(LocalDateTime.class, new LocalDateTimeTypeHandler());
        };
    }
}

方式B:MyBatis配置文件实现

在mybatis-config.xml中直接注册自定义处理器,覆盖默认映射:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeHandlers>
        <!-- 注册自定义处理器,会覆盖同类型的默认实现 -->
        <typeHandler handler="my.mapper.typehandlers.LocalDateTimeTypeHandler"/>
    </typeHandlers>
</configuration>

然后在Spring Boot配置中指定该文件路径:

mybatis.config-location=classpath:mybatis-config.xml

方法2:在Mapper的@Result中显式指定全类名

若仅需局部字段生效,可在@Result中明确指定自定义处理器的完整类路径:

@Results(id = "statusResult", value = {
        @Result(property = "id", column = "id", id = true),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "enqueueDone", column = "enqueue_done"),
        @Result(property = "enqueuedTime", column = "enqueued_time", 
                typeHandler = my.mapper.typehandlers.LocalDateTimeTypeHandler.class)
})

方法3:调整自定义处理器加载顺序

MyBatis中后加载的类型处理器会覆盖先加载的,可通过Spring注解调整自定义处理器的加载优先级,确保它在自带处理器之后被注册:

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.*;
import java.time.LocalDateTime;

@Component
@Order(Ordered.LOWEST_PRECEDENCE) // 确保晚于自带处理器加载
@MappedJdbcTypes(value=JdbcType.TIMESTAMP)
@MappedTypes(value = LocalDateTime.class)
public class LocalDateTimeTypeHandler extends BaseTypeHandler<LocalDateTime> {
    // 原有实现代码...
}

验证方式

配置完成后调试时,观察setNonNullParameter或getNullableResult方法的调用栈,确认执行的是自定义处理器的代码,而非MyBatis自带的org.apache.ibatis.type.LocalDateTimeTypeHandler。

内容的提问来源于stack exchange,提问作者Daniel Cosio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:57:08