当Wrapper查询条件有枚举,且注册了全局枚举typeHandler的情况下,typeHandler无法对枚举生效的问题
luo-zhan opened this issue · comments
Robot.L commented
场景复现:
枚举定义,实现统一枚举接口:
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的判断
}
...
}