
MyBatis 的 TypeHandler 是 Java 对象与数据库字段之间类型转换的桥梁,它不是靠配置“自动猜”,而是通过明确实现接口方法,在参数设置和结果读取两个关键环节完成双向转换。
核心转换发生在两个阶段
所有转换逻辑都围绕 SQL 执行生命周期展开:
-
入参转换(写库):调用
setParameter()方法,把 Java 对象属性值转成 JDBC 兼容类型,再交给PreparedStatement.setXXX()设置到 SQL 占位符中。 -
出参转换(读库):调用三个重载的
getResult()方法之一,从ResultSet或CallableStatement中取出原始 JDBC 值(如getInt()、getString()),再封装或转换为对应的 Java 类型返回。
推荐方式:继承 BaseTypeHandler 抽象类
直接实现 TypeHandler 接口需覆盖全部四个方法,但多数场景只需关注非空逻辑。MyBatis 提供了 BaseTypeHandler 作为基类,它已统一处理 null 值(自动调用 ps.setNull() 或返回 null),你只需专注业务转换:
- 重写
setNonNullParameter(PreparedStatement, int, T, JdbcType):例如对LocalDateTime调用ps.setTimestamp(i, Timestamp.valueOf(parameter))。 - 重写三个
getNullableResult(...)方法:例如从ResultSet取字符串后解析为枚举,或把数据库存的 JSON 字符串反序列化为对象。
让 MyBatis 知道该用哪个 TypeHandler
注册方式决定生效范围:
立即学习“Java免费学习笔记(深入)”;
-
全局注册:在 MyBatis 配置文件(
mybatis-config.xml)中声明:
<typeHandlers>
<typeHandler handler="com.example.MyEnumTypeHandler" javaType="com.example.StatusEnum"/>
</typeHandlers> -
局部指定:在 Mapper XML 的
<resultMap>或<parameterMap>中,给字段/参数显式标注:
<result property="status" column="status_code" javaType="com.example.StatusEnum" typeHandler="com.example.MyEnumTypeHandler"/> -
注解注册:在自定义 TypeHandler 类上加
@MappedTypes(StatusEnum.class)和@MappedJdbcTypes(JdbcType.VARCHAR),启动时自动扫描注册。
常见自定义场景示例
内置处理器无法覆盖的典型需求:
- 枚举类映射:数据库存字符串(如 "ACTIVE")或数字(如 1),Java 侧用枚举,TypeHandler 负责字符串 ↔ 枚举实例的双向转换。
-
JSON 字段:数据库用 TEXT 或 JSON 类型存对象序列化内容,TypeHandler 使用 Jackson/Fastjson 完成
String ↔ Object转换。 -
敏感字段加解密:写库前加密、读库后解密,可在
setNonNullParameter和getNullableResult中嵌入加解密逻辑。 -
时间精度适配:如将
LocalDateTime存为带毫秒的TIMESTAMP,避免默认截断到秒。


















