如何让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
相关产品推荐
相关产品推荐

