Mybatis TypeHandler 的使用

johnchou發表於2021-09-09

1,列舉類

public enum GenderEnum implements CodeDescEnum {
    /**
     * 0未知,1男,2女
     */
    UNKNOWN(0, "未知"),
    MALE(1, "男"),
    FEMALE(2, "女");

    private Integer code;
    private String desc;

    GenderEnum(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    @Override
    public String getDesc() {
        return desc;
    }

    @Override
    public Integer getCode() {
        return code;
    }
}

2,編寫Hanlder 繼承CodeIdentifyEnumHandler

public class GenderEnumHandler extends CodeIdentifyEnumHandler<GenderEnum> {
    public GenderEnumHandler() {
        super(GenderEnum.class);
    }
}

3,CodeIdentifyEnumHandler

public abstract class CodeIdentifyEnumHandler<T extends Enum<T> & CodeDescEnum> extends BaseTypeHandler<T> {

    private Class<T> type;

    /**
     * 設定配置檔案設定的轉換類以及列舉類內容,供其他方法更便捷高效的實現
     *
     * @param type 配置檔案中設定的轉換類
     */
    public CodeIdentifyEnumHandler(Class<T> type) {
        if (type == null)
            throw new IllegalArgumentException("Type argument cannot be null");
        this.type = type;
    }


    @Override
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return CodeDescEnum.getFromCodeOrThrow(type, rs.getInt(columnName));
    }

    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return CodeDescEnum.getFromCodeOrThrow(type, rs.getInt(columnIndex));
    }

    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return CodeDescEnum.getFromCodeOrThrow(type, cs.getInt(columnIndex));
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter.getCode());
    }
}


4 , 看一下CodeDescEnum

public interface CodeDescEnum {
    Map<Class, Map<String, CodeDescEnum>> descEnumCache = new HashMap<>();
    Map<Class, Map<Integer, CodeDescEnum>> codeEnumCache = new HashMap<>();

    @SuppressWarnings(value = {"unchecked"})
    static <Y extends CodeDescEnum> Optional<Y> getFromDescOpt(Class<Y> clazz, String desc) {
        Map<String, CodeDescEnum> clazzEnumMap = descEnumCache.get(clazz);

        // 初始化enumMap
        if (clazzEnumMap == null) {
            clazzEnumMap = new HashMap<>();

            for (Y type : clazz.getEnumConstants()) {
                clazzEnumMap.put(type.getDesc(), type);
            }
            descEnumCache.put(clazz, clazzEnumMap);
        }

        return Optional.ofNullable((Y) clazzEnumMap.get(desc));
    }

    @SuppressWarnings(value = {"unchecked"})
    static <T extends CodeDescEnum> T getFromDescOrNull(Class<T> clazz, String desc) {
        Optional<? extends CodeDescEnum> codeIdentifyEnumOpt = getFromDescOpt(clazz, desc);
        return (T) codeIdentifyEnumOpt.orElse(null);
    }

    @SuppressWarnings(value = {"unchecked"})
    static <T extends CodeDescEnum> T getFromDescOrThrow(Class<T> clazz, String desc) {
        Optional<? extends CodeDescEnum> codeIdentifyEnumOpt = getFromDescOpt(clazz, desc);
        if (codeIdentifyEnumOpt.isPresent()) {
            return (T) codeIdentifyEnumOpt.get();
        }
        throw new CommonException(CommonErrorCode.UNKNOWN_ERROR, "不存在的" + clazz.getSimpleName() + "型別", "不存在的" + clazz.getSimpleName() + "型別desc=" + desc);
    }


    @SuppressWarnings(value = {"unchecked"})
    static <Y extends CodeDescEnum> Optional<Y> getFromCodeOpt(Class<Y> clazz, Integer code) {
        Map<Integer, CodeDescEnum> clazzEnumMap = codeEnumCache.get(clazz);

        // 初始化enumMap
        if (clazzEnumMap == null) {
            clazzEnumMap = new HashMap<>();

            for (Y type : clazz.getEnumConstants()) {
                clazzEnumMap.put(type.getCode(), type);
            }
            codeEnumCache.put(clazz, clazzEnumMap);
        }

        return Optional.ofNullable((Y) clazzEnumMap.get(code));
    }

    @SuppressWarnings(value = {"unchecked"})
    static <T extends CodeDescEnum> T getFromCodeOrNull(Class<T> clazz, Integer code) {
        Optional<? extends CodeDescEnum> codeIdentifyEnumOpt = getFromCodeOpt(clazz, code);
        return (T) codeIdentifyEnumOpt.orElse(null);
    }

    @SuppressWarnings(value = {"unchecked"})
    static <T extends CodeDescEnum> T getFromCodeOrThrow(Class<T> clazz, Integer code) {
        Optional<? extends CodeDescEnum> codeIdentifyEnumOpt = getFromCodeOpt(clazz, code);
        if (codeIdentifyEnumOpt.isPresent()) {
            return (T) codeIdentifyEnumOpt.get();
        }
        throw new CommonException(CommonErrorCode.UNKNOWN_ERROR, "不存在的" + clazz.getSimpleName() + "型別", "不存在的" + clazz.getSimpleName() + "型別code=" + code);
    }

    String getDesc();

    Integer getCode();
}

5,po中的配置

public class UserPO implements Serializable {
   ...
    @ColumnType(typeHandler = GenderEnumHandler.class)
    private GenderEnum gender;

6,mapper.xml中的配置

 <resultMap id="BaseResultMap" type="com.yiwise.core.dal.entity.UserPO">
       ...
        <result column="gender" jdbcType="INTEGER" property="gender"
                typeHandler="com.yiwise.core.model.enums.handler.GenderEnumHandler"/>
 </resultMap>

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4422/viewspace-2821260/,如需轉載,請註明出處,否則將追究法律責任。

相關文章