Mybatis处理枚举

Springboot 集成 Mybatis 处理枚举
mybatis自带了两个处理枚举的 类 EnumTypeHandler ,EnumOrdinalTypeHandler 一个使用枚举的name,一个使用枚举的下标;
做项目时,会节省数据库资源,对一些固定的值,直接在代码里定义为枚举,枚举存放一个code 将这个code存入数据库; 比如男女 存放1 ,0 而不是男女这两个字;
处理这些枚举的时候需要我们自定义枚举处理;

两种实现方案:
定义接口 BaseEnum

public interface BaseEnum {
    String getValue();
}

这里定义为String类型;因为在jdbc里面String基本能映射大多数数据库数据类型
也可以使用其他类型
定义枚举类型处理器

/**
 * 使用BaseEnum 指定枚举会映射的数据
 * @param <E> BaseEnum
 * @author jian.jiang
 * 处理枚举映射
 */
@MappedTypes(BaseEnum.class)
public class EnumTypeHandler<E extends Enum<E>&BaseEnum> extends BaseTypeHandler<E> {

    private final HashMap<String, E> eMap = new HashMap<>();

    public EnumTypeHandler(Class<E> type) {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }

        for (E e : type.getEnumConstants()) {
            eMap.put(e.getValue(), e);
        }
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType)
            throws SQLException {
        if (jdbcType == null)
            ps.setString(i, parameter.getValue());
        else
            ps.setObject(i, parameter.getValue(), jdbcType.TYPE_CODE);
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName)
            throws SQLException {
        return eMap.get(rs.getString(columnName));
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex)
            throws SQLException {
        return eMap.get(rs.getString(columnIndex));
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return eMap.get(cs.getString(columnIndex));
    }
}

更改配置


mybatis:
  mapper-locations: classpath:**/mapper/*.xml,classpath:**/dao/*.xml
  configuration:
    default-enum-type-handler: demo.mybatis.typehandler.EnumTypeHandler

这里的配置default-enum-type-handler会替换掉TypeHandlerRegistry 里面的defaultEnumTypeHandler

枚举定义时实现BaseEnum接口就可以了,例如:

@AllArgsConstructor
@Getter
public enum SexEnum implements BaseEnum {
    MAN(1),
    WOMAN(0),
    UNKNOW(2),
    ;

    @JsonValue
    public final Integer code;


    @Override
    public String getValue() {
        return code.toString();
    }
}

如果项目中使用rest接口,返回前端时,枚举也需要转为指定的Code,一般会使用@JsonValue注解
可以借助这个注解,省去再写接口,实现接口的步骤

定义枚举处理器


/**
 * 与页面vo共用一个注解
 * @author jianjiang
 */
public class JsonEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {

    private final Map<String, E> key2value = new HashMap<>();
    private final Map<E, String> value2key = new HashMap<>();

    public JsonEnumTypeHandler(Class<E> type) throws IllegalAccessException {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }

        E[] enumConstants = type.getEnumConstants();
        Field[] declaredFields = type.getDeclaredFields();
        Field jsonValue = null;
        int count = 0;
        for (Field e : declaredFields) {
            if (e.isAnnotationPresent(JsonValue.class)) {
                jsonValue = e;
                count++;
            }
        }

        if (count > 1) {
            throw new IllegalArgumentException("exist more than one  Annotation JsonValue" + type.getName());
        } else if (count == 1) {
            if (!jsonValue.isAccessible())
                    jsonValue.setAccessible(true);  
            for (E e : enumConstants) {
                key2value.put(String.valueOf(jsonValue.get(e)), e);
                value2key.put(e, String.valueOf(jsonValue.get(e)));
            }
        } else { //如果没有,按照name进行设置
            for (E e : enumConstants) {
                key2value.put(e.name(), e);
                value2key.put(e, e.name());
            }
        }
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        if (jdbcType == null) {
            ps.setString(i, value2key.get(parameter));
        } else {
            ps.setObject(i, value2key.get(parameter), jdbcType.TYPE_CODE);
        }
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String s = rs.getString(columnName);
        return s == null ? null : key2value.get(s);
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String s = rs.getString(columnIndex);
        return s == null ? null : key2value.get(s);
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String s = cs.getString(columnIndex);
        return s == null ? null : key2value.get(s);
    }
}

配置那替换为这个类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值