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

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配置文件手动注册:

  1. 新建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>
  1. 在application.properties中指定配置文件路径:
mybatis.config-location=classpath:mybatis-config.xml

必检项

  • 确认mybatis.type-handlers-package配置的包路径包含FooHandler;
  • 枚举类Foo的getValue()方法正确实现;
  • 数据库对应列类型为VARCHAR,与JdbcType.VARCHAR匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:43:35