MyBatis自定义枚举TypeHandler无法同时支持读写的问题
解决MyBatis枚举TypeHandler全局读写生效问题
问题根源
仅添加@MappedTypes(Foo.class)时,写入阶段MyBatis因JDBC类型匹配逻辑未选中自定义处理器,直接写入枚举名称;仅添加@MappedJdbcTypes(JdbcType.VARCHAR)时,该注解默认forResult=false,仅对写入操作生效,读取数据时无法匹配处理器。
修复方案1:修正注解配置
给FooHandler同时配置针对写入和读取场景的@MappedJdbcTypes注解,覆盖全流程:
@MappedTypes(Foo.class) @MappedJdbcTypes(JdbcType.VARCHAR) // 默认forResult=false,处理写入 @MappedJdbcTypes(value = JdbcType.VARCHAR, forResult = true) // 处理读取 public class FooHandler implements TypeHandler<Foo> { @Override public void setParameter(PreparedStatement ps, int i, Foo parameter, JdbcType jdbcType) throws SQLException { if (parameter == null) { ps.setNull(i, Types.VARCHAR); return; } ps.setString(i, parameter.getValue()); } @Override public Foo getResult(ResultSet rs, String columnName) throws SQLException { return convertToEnum(rs.getString(columnName)); } @Override public Foo getResult(ResultSet rs, int columnIndex) throws SQLException { return convertToEnum(rs.getString(columnIndex)); } @Override public Foo getResult(CallableStatement cs, int columnIndex) throws SQLException { return convertToEnum(cs.getString(columnIndex)); } private Foo convertToEnum(String value) { if (value == null) return null; for (Foo foo : Foo.values()) { if (foo.getValue().equals(value)) { return foo; } } throw new IllegalArgumentException("Unknown enum value: " + value); } }
修复方案2:全局注册TypeHandler(配置文件方式)
若注解方案仍不生效,可通过MyBatis配置文件手动注册:
- 新建
mybatis-config.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeHandlers> <typeHandler handler="com.example.FooHandler" javaType="com.example.Foo" jdbcType="VARCHAR"/> </typeHandlers> </configuration>
- 在
application.properties中指定配置文件路径:
mybatis.config-location=classpath:mybatis-config.xml
必检项
- 确认
mybatis.type-handlers-package配置的包路径包含FooHandler; - 枚举类
Foo的getValue()方法正确实现; - 数据库对应列类型为VARCHAR,与
JdbcType.VARCHAR匹配。
内容的提问来源于stack exchange,提问作者Egor
相关产品推荐
相关产品推荐

