MyBatis自定义数据映射TypeHandler

  • 需求:自定义一个将枚举存为Byte类型的TypeHandler。

  • VO类:

    public class JrTradeUser implements Serializable {
    
        private static final long serialVersionUID = 5401255707141549736L;
    
        // 主键
        private Long id;
    
        // 状态
        private Byte state;
    
        // 姓名
        private String realName;
    
        // 生日
        private Date birthday;
    
        // 用户风险测评问卷等级
        private RiskLevelEnum userRisk;
    
        /**
         * getters && setters
         */
    }
  • 处理类:

        public class EnumStatusHandler extends BaseTypeHandler<RiskLevelEnum> {
    
            private Class type;
    
            private final RiskLevelEnum[] enums;
    
            /**
             * 构造enums数组以及type
             *
             * @param type 待转换枚举类
             */
            public EnumStatusHandler(Class type) {
                if (type == null) {
                    throw new IllegalArgumentException("Type argument cannot be null");
                }
                this.type = type;
                this.enums = type.getEnumConstants();
                if (this.enums == null) {
                    throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");
                }
            }
    
            @Override
            public void setNonNullParameter(PreparedStatement ps, int i, RiskLevelEnum parameter, JdbcType jdbcType) throws SQLException {
                // baseTypeHandler已经帮我们做了parameter的null判断
                ps.setInt(i, parameter.getValue());
            }
    
            @Override
            public RiskLevelEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
                // 根据数据库存储类型决定获取类型,本例子中数据库中存放Byte类型
                Byte i = rs.getByte(columnName);
    
                if (rs.wasNull()) {
                    return null;
                } else {
                    // 根据数据库中的code值,定位RiskLevelEnum子类
                    return locateEnumStatus(i);
                }
            }
    
            @Override
            public RiskLevelEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
                // 根据数据库存储类型决定获取类型,本例子中数据库中存放Byte类型
                Byte i = rs.getByte(columnIndex);
                if (rs.wasNull()) {
                    return null;
                } else {
                    // 根据数据库中的code值,定位RiskLevelEnum子类
                    return locateEnumStatus(i);
                }
            }
    
            @Override
            public RiskLevelEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
                // 根据数据库存储类型决定获取类型,本例子中数据库中存放Byte类型
                Byte i = cs.getByte(columnIndex);
                if (cs.wasNull()) {
                    return null;
                } else {
                    // 根据数据库中的code值,定位RiskLevelEnum子类
                    return locateEnumStatus(i);
                }
            }
    
            /**
             * 枚举类型转换
             *
             * @param code 数据库中存储的自定义code属性
             * @return code对应的枚举类
             */
            private RiskLevelEnum locateEnumStatus(Byte code) {
                for (RiskLevelEnum status : enums) {
                    if (status.getValue() == code) {
                        return status;
                    }
                }
                throw new IllegalArgumentException("未知的枚举类型:" + code + ",请核对" + type.getSimpleName());
            }
        }
  • Mybatis xml文件:

    <resultMap id="BaseResultMap" type="xxx.xxx.xxx.JrTradeUser">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <result column="state" property="state" jdbcType="TINYINT"/>
        <result column="real_name" property="realName" jdbcType="VARCHAR"/>
        <result column="birthday" property="birthday" jdbcType="DATE"/>
        <result column="user_risk" property="userRisk" typeHandler="xxx.xxx.xxx.EnumStatusHandler"/>
    resultMap>
    
    <sql id="INSERT">
        INSERT INTO
        xxx
        (state, real_name, birthday, user_risk)
        VALUES
        (
            #{state,jdbcType=TINYINT},
            #{realName,jdbcType=VARCHAR},
            #{birthday,jdbcType=DATE},
            #{userRisk,typeHandler=xxx.xxx.xxx.EnumStatusHandler}
        )
    sql>
    
    <sql id="UPDATE">
        UPDATE
        xxx
        <set>
            <if test="state != null">
            state = #{state,jdbcType=TINYINT},
        if>
        <if test="realName != null">
            real_name = #{realName,jdbcType=VARCHAR},
        if>
        <if test="birthday != null">
            birthday = #{birthday,jdbcType=DATE},
        if>
        <if test="userRisk != null">
            user_risk = #{userRisk,typeHandler=xxx.xxx.xxx.EnumStatusHandler}
        if>
        set>
        WHERE
        id = #{id,jdbcType=BIGINT}
    sql>
    
    <sql id="FIND_BY_ID">
        SELECT
        id, state, real_name, birthday, user_risk
        FROM
        xxx
        WHERE
        id = #{id,jdbcType=BIGINT}
    sql>

你可能感兴趣的:(J2EE)