16、通用枚举类型处理(一)

来源:互联网 发布:网络优化塔工2017招聘 编辑:程序博客网 时间:2024/06/10 12:29

问题

如果一个项目中,有几十个,几百个,甚至更多的枚举类型怎么办?

如果遇到一个枚举类,写一个TypeHandle,这样的话,枚举类的处理器会剧增。
不仅如此,你会发现,枚举类的处理器几乎大同小异。

解决的思路

定义一个万能的枚举转换处理器,使用泛型实现

定义枚举接口

package com.lf;/** * Created by LF on 2017/6/12. */public interface BaseEnum<E extends Enum<?>, T> {    T getCode();    String getName();    E of(String code);}

实现枚举接口,定义枚举

package com.lf.dict;import com.lf.BaseEnum;import lombok.ToString;import java.util.HashMap;import java.util.Map;/** * Created by LF on 2017/6/12. */@ToStringpublic enum Gender implements BaseEnum<Gender, Integer> {    MAN(1, "男"),    WOMAN(2, "女");    static Map<Integer, Gender> enumMap = new HashMap<>();    static {        Gender[] values = Gender.values();        for (Gender value : values) {            enumMap.put(value.getCode(), value);        }    }    private Integer code;    private String name;    Gender(Integer code, String name) {        this.code = code;        this.name = name;    }    @Override    public Integer getCode() {        return code;    }    public void setCode(Integer code) {        this.code = code;    }    @Override    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public Gender of(String code) {        return enumMap.get(code);    }}

定义万能枚举转换处理器

package com.lf.typehandle;import com.lf.BaseEnum;import org.apache.ibatis.type.BaseTypeHandler;import org.apache.ibatis.type.JdbcType;import org.apache.ibatis.type.MappedJdbcTypes;import org.apache.ibatis.type.MappedTypes;import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;/** * Created by LF on 2017/6/12. */@MappedTypes(basePackage = {"com.lf.dict"})@MappedJdbcTypes(value = JdbcType.INTEGER, includeNullJdbcType = true)public class BaseEnumTypeHandle<E extends BaseEnum> extends BaseTypeHandler<E> {    private Class<E> type;    private E[] enums;    /**     * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现     *     * @param type 配置文件中设置的转换类     */    public BaseEnumTypeHandle(Class<E> type) {        if (type == null)            throw new IllegalArgumentException("Type argument cannot be null");        this.type = type;        this.enums = type.getEnumConstants();        Class<?>[] interfaces = type.getInterfaces();        for (Class<?> anInterface : interfaces) {            Object[] enumConstants = anInterface.getEnumConstants();        }//        this.enums =  type.getGenericInterfaces();        if (this.enums == null)            throw new IllegalArgumentException(type.getSimpleName()                    + " does not represent an enum type.");    }    @Override    public void setNonNullParameter(PreparedStatement ps, int i, E parameter,                                    JdbcType jdbcType) throws SQLException {        //BaseTypeHandler已经帮我们做了parameter的null判断        ps.setObject(i, (String) parameter.getCode(), jdbcType.TYPE_CODE);    }    @Override    public E getNullableResult(ResultSet rs, String columnName)            throws SQLException {        // 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型        String i = rs.getString(columnName);        if (rs.wasNull()) {            return null;        } else {            // 根据数据库中的value值,定位PersonType子类            return locateEnumStatus(i);        }    }    @Override    public E getNullableResult(ResultSet rs, int columnIndex)            throws SQLException {        // 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型        String i = rs.getString(columnIndex);        if (rs.wasNull()) {            return null;        } else {            // 根据数据库中的value值,定位PersonType子类            return locateEnumStatus(i);        }    }    @Override    public E getNullableResult(CallableStatement cs, int columnIndex)            throws SQLException {        // 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型        String i = cs.getString(columnIndex);        if (cs.wasNull()) {            return null;        } else {            // 根据数据库中的value值,定位PersonType子类            return locateEnumStatus(i);        }    }    /**     * 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷     *     * @param value 数据库中存储的自定义value属性     * @return value对应的枚举类     */    private E locateEnumStatus(String value) {        for (E e : enums) {            if (e.getCode().equals(value)) {                return e;            }        }        throw new IllegalArgumentException("未知的枚举类型:" + value + ",请核对" + type.getSimpleName());    }}

配置

 <typeHandlers>        <typeHandler  handler="com.lf.typehandle.BaseEnumTypeHandle" javaType="com.lf.dict.Gender"/>    </typeHandlers>

配置需要转换的字段

  <resultMap id="BaseResultMap" type="com.lf.entity.Blog">    <id column="id" jdbcType="VARCHAR" property="id" />    <result column="title" jdbcType="VARCHAR" property="title" />    <result column="url" jdbcType="VARCHAR" property="url" typeHandler="com.lf.typehandle.BaseEnumTypeHandle"/>    <result column="userid" jdbcType="VARCHAR" property="userid"  />  </resultMap>

这样,我们就不需要为每一个枚举创建一个Handler去自动转换数据库中的枚举了。
仅是这样的话和org.apache.ibatis.type.EnumOrdinalTypeHandler就没有什么区别了,我们写这个类就完全没有必要了

原创粉丝点击