springboot+mybatis 实现自定义枚举类型的处理

自定义的枚举类要实现接口IBaseEnum<T>。它的代码如下:

@JsonSerialize(using = JsonEnumSerializer.class) // json序列化
public interface IBaseEnum<T> extends Serializable {

    T getValue();
    String getLabel();
}

一、枚举类型数据返回前端的处理

对枚举类序列化的实现

/**
 * @author shipc 2019/12/31 10:42
 * @version 1.0.0
 */
public class JsonEnumSerializer extends JsonSerializer<IBaseEnum> {

    private static Logger log = LoggerFactory.getLogger(JsonEnumSerializer.class);
    @Override
    public void serialize(IBaseEnum iBaseEnum, JsonGenerator jsonGenerator, SerializerProvider serializerProvider){
        HashMap<String, Object> map = new HashMap<>();
        map.put("value", iBaseEnum.getValue());
        map.put("label", iBaseEnum.getLabel());
        try {
            serializerProvider.defaultSerializeValue(map, jsonGenerator);
        } catch (IOException e) {
            log.error("枚举类序列化错误", e);
            throw new BaseException(BaseResultCode.SERIALIZER_ERROR);
        }
    }
}

使用: 实现IBaseEnum<T>, 直接返回枚举对象。

示例:

public enum ApplyType implements IBaseEnum<Integer> {
    AUTO(1, "自动申请"),
    MANUAL(0, "手动申请");
    // 省略了其他代码
}

返回数据:

{
    "success": true,
    "code": "0000000",
    "message": "成功",
    "data": {
        "label": "自动申请",
        "value": 1
    }
}

二、枚举类型存入数据库的处理

1.首先需要实现IBaseEnum<T>接口;

2.其次要将具体的类加到BaseEnumHandler类@MappedTypes(value = {})中。如面代码ApplyType.class,RepairOrderStatus.class, ConsumableOrderStatus.class,一样;

/**
 * @author shipc 2019/12/31 14:06
 * @version 1.0.0
 */
@MappedTypes(value = {RepairOrderStatus.class, ConsumableOrderStatus.class, ApplyType.class})
public class BaseEnumHandler<T extends IBaseEnum> extends BaseTypeHandler<T> {
    private Class<T> type;
    private T[] enums;

    public BaseEnumHandler(Class<T> type) {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }
        this.type = type;
        this.enums = type.getEnumConstants();

    }

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, T t, JdbcType jdbcType) throws SQLException {
        if (jdbcType == null) {
            preparedStatement.setString(i, t.getValue().toString());
        } else {
            preparedStatement.setObject(i, t.getValue(), jdbcType.TYPE_CODE);
        }
    }

    @Override
    public T getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return getEnumByValue(resultSet.getObject(s));
    }

    private T getEnumByValue(Object object) {
        if (object == null) return null;
        for (T t : enums) {
            if (t.getValue().equals(object) || t.getValue().toString().equals(object.toString())) {
                return t;
            }
        }
        return null;
    }

    @Override
    public T getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return getEnumByValue(resultSet.getObject(i));
    }

    @Override
    public T getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return getEnumByValue(callableStatement.getObject(i));
    }

    public Class<T> getType() {
        return type;
    }

    public void setType(Class<T> type) {
        this.type = type;
    }

    public T[] getEnums() {
        return enums;
    }

    public void setEnums(T[] enums) {
        this.enums = enums;
    }
}

3.最后要在mapper文件中对应字段的位置配置jdbcType和typeHandler,如下方订单状态:

order_state = #{item,jdbcType=INTEGER,typeHandler=com.rayootech.system.mybatis.handler.BaseEnumHandler}

这样存入数据库的值就是枚举类value的值。

三、从数据库查出是枚举类型的处理

这和“枚举类型存入数据库的处理”的前两步是一样的。

最后一步是要定义一个<resultMap>,在枚举类型对应的<result>中配置javaType和typeHandler,如下面代码ApplyType所示:

<result property="applyType" column="ot_apply_type" javaType="com.rayootech.system.domain.consumable.ApplyType"
        typeHandler="com.rayootech.system.mybatis.handler.BaseEnumHandler"/>

猜你喜欢

转载自www.cnblogs.com/shipc/p/12584472.html
今日推荐