跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

解决XML映射中的数据类型转换问题

MyBatis 中自定义 typeHandler 不生效,需全局注册并显式声明于 resultMap;#{} 支持类型转换,${} 仅字符串拼接;JSON/LocalDateTime 等需专用 TypeHandler;嵌套 resultMap 中 typeHandler 需单独指定,且必须双向实现。 MyBatis 中
resultMap
的 typeHandler 不生效?检查注册方式和 作用域 MyBatis 默认对基本类型(
String
、
Integer
、
Date
)有内置
TypeHandler
,但自定义类型(如枚举、
LocalDateTime
、JSON 字符串转对象)必须显式绑定,否则会报
Cannot convert value of type 'java.lang.String' to required type
或字段为
null
。 常见错误是只在
resultMap
里写了
typeHandler
属性,却没在全局或映射语句中真正启用:
resultMap
中的
仅对当前字段生效,但前提是该
TypeHandler
已被 MyBatis 加载(即已注册) 未注册的
TypeHandler
会被静默忽略,不会报错,只返回
null
推荐在
mybatis-config.xml
中全局注册:
若用 Spring Boot + MyBatis-Plus,改用
@Configuration
类中注册
Configuration.addTypeHandler(...)
XML 中
#{}
和
${}
对数据类型的影响完全不同
#{}
是预编译参数占位符,MyBatis 会根据字段类型自动选择
TypeHandler
;
${}
是字符串拼接,绕过所有类型转换逻辑,直接转成
String
后拼入 SQL —— 这是多数“类型丢失”的根源。 例如传入
LocalDateTime
:
WHERE create_time > #{startTime}
→ 正确:MyBatis 调用
LocalDateTimeTypeHandler
,生成带时区的 JDBC 参数
WHERE create_time > '${startTime}'
→ 错误:调用
toString()
,结果可能是
"2024-05-20T14:30:00"
,数据库报语法错误或 隐式转换 失败
ORDER BY ${sortField}
属于合法动态列名场景,但绝不能用于值参数 PostgreSQL / MySQL 的
jsonb
/
JSON
字段在 XML 映射中需要专用 TypeHandler 数据库原生 JSON 类型无法被 MyBatis 默认处理,直接映射到
String
会丢失结构,映射到
Object
则抛
ClassCastException
。 Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 必须使用第三方
TypeHandler
,例如 Jackson: Maven 引入:
com.fasterxml.jackson.core:jackson-databind
和
org.mybatis:mybatis-typehandlers-jsr310
(后者仅支持 JSR310 时间类型,不支持 JSON) 自定义
JsonTypeHandler
,重写
setNonNullParameter
和
getNullableResult
,内部用
ObjectMapper
序列化/反序列化 在
resultMap
中指定:
注意:MySQL 8.0+ 的
JSON
类型需 JDBC 驱动开启
allowPublicKeyRetrieval=true
才能读取二进制 JSON 值,否则返回空 嵌套
resultMap
时子映射的 typeHandler 容易被父级覆盖 当主
resultMap
引用另一个
resultMap
(如
),子映射中声明的
typeHandler
可能被忽略——MyBatis 优先使用父级
resultMap
的类型推导逻辑。 解决方法很直接: 不要依赖嵌套映射自动继承
typeHandler
,每个字段都显式声明
typeHandler
若子对象字段类型与数据库列类型不一致(如 DB 存
VARCHAR
,Java 期望
Enum
),必须在子
resultMap
的
中写死
typeHandler
避免用
autoMapping="true"
,它会跳过所有手动配置的
typeHandler
最常被忽略的一点:
TypeHandler
必须同时实现
setParameter
(写入)和
getResult
(读取),缺一不可;只重写一半会导致单向转换失败,现象是插入正常、查询为
null
。

相关文章