mybatis-flex / mybatis-flex

mybatis-flex is an elegant Mybatis Enhancement Framework

Home Page:https://mybatis-flex.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

当Wrapper查询条件有枚举,且注册了全局枚举typeHandler的情况下,typeHandler无法对枚举生效的问题

luo-zhan opened this issue · comments

场景复现:

枚举定义,实现统一枚举接口:

public interface BaseEnum {

    int getValue();
}
public enum Sex implements BaseEnum {
    MALE(1),
    FEMALE(2);

    private final int value;

    Sex(Integer value) {
        this.value = value;
    }

    @Override
    public int getValue() {
        return value;
    }
}

自定义TypeHandler:

public class EnumTypeHandler<E extends Enum<E> & BaseEnum> extends BaseTypeHandler<E> {
    private final Class<E> enumClass;

    public EnumTypeHandler(Class<E> enumClass) {
        this.enumClass = enumClass;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        Integer value = parameter.getValue();
        ps.setObject(i, value);
    }
  // 省略

注册typeHandler:

FlexConfiguration configuration = new FlexConfiguration();
configuration.setDefaultEnumTypeHandler(EnumTypeHandler.class);
...

测试代码:

  QueryWrapper query = new QueryWrapper()
            .select()
            .from(ACCOUNT).where(ACCOUNT.SEX.in(Sex.MALE, Sex.FEMALE));

结果,错误地使用了枚举的name作为查询条件,本应该使用枚举的value作为查询条件

SELECT * FROM `tb_account` WHERE `sex` IN ('MALE', 'FEMALE')

原因分析:

QueryWrapper给字段设置枚举条件时没有判断该枚举字段是否注册了typeHandler:

 private static void addParam(List<Object> paras, Object value) {
         ...
        } else if (value.getClass().isEnum()) {
              EnumWrapper enumWrapper = EnumWrapper.of(value.getClass());
              if (enumWrapper.hasEnumValueAnnotation()) {
                  paras.add(enumWrapper.getEnumValue((Enum) value));
              } else {
                  paras.add(((Enum<?>) value).name());  // 如果没有使用@EnumValue就会塞入name,缺少typeHandler的判断
              }
       ...
}