mybatis入库的Handler解读

来源:互联网 发布:山寨币 冷钱包源码 编辑:程序博客网 时间:2024/06/06 03:56

需要将前台传递过来的枚举类处理为枚举的值。所以抄着网络一段处理枚举的代码。

解读过程

定义枚举类时候需要实现一个数字装换接口。具体代码如下:

@EnumTags(alias = "orderStatusEnum")public enum OrderStatusEnum implements IntEnum<OrderStatusEnum> {    NEW(1),    UnPay(2),    UnConfirm(3),    Confirm(4),    ConfirmFailed(5),    UserCancel(6),    TimeoutCancel(7),    MerchantCancel(8),    MerchantRefusedCancel(9),    ErpOrderFail(10);    private int value;    OrderStatusEnum(int value) {        this.value = value;    }    @Override    public int getIntValue() {        return value;    }    @Override    public String toString() {        return String.valueOf(value);    }}

定义和数据库请求的handler。复制网络如下

/** * 处理使用mybatis时候不能查出enmu类和插入时候不能插入titint * Created by lijianzhen1 on 2017/3/16. */public class EnumTypeHandler<E extends Enum<E> & IntEnum<E>> extends BaseTypeHandler<IntEnum> {    private Class<IntEnum> clazz;    public EnumTypeHandler(Class<IntEnum> enumType) {        if (enumType == null)            throw new IllegalArgumentException("enumType argument cannot be null");        this.clazz = enumType;    }    /**     * 将数据库映射的值转化为对应的枚举值     *     * @param code     * @return     */    private IntEnum convert(int code) {        IntEnum[] enumConstants = clazz.getEnumConstants();        for (IntEnum im : enumConstants) {            if (im.getIntValue() == code)                return im;        }        return null;    }    @Override    public void setNonNullParameter(PreparedStatement preparedStatement, int i, IntEnum intEnum, JdbcType jdbcType) throws SQLException {        preparedStatement.setInt(i, intEnum.getIntValue());    }    @Override    public IntEnum getNullableResult(ResultSet resultSet, String columnName) throws SQLException {        return convert(resultSet.getInt(columnName));    }    @Override    public IntEnum getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {        return convert(resultSet.getInt(columnIndex));    }    @Override    public IntEnum getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {        return convert(callableStatement.getInt(columnIndex));    }}

别的handler处理都没有构造函数去构造,但是上边的为什么会有一个构造参数。这个是怎么实现的。
先找到对应的xml解析registry类XMLMapperBuilder。

//解析xsd注册得xml部分ParameterMapping parameterMapping = builderAssistant.buildParameterMapping(parameterClass, property, javaTypeClass, jdbcTypeEnum, resultMap, modeEnum, typeHandlerClass, numericScale);
//获得需要持久化解析的参数对象 Class parameterType = parameterMapBuilder.type();Class<?> javaTypeClass = resolveParameterJavaType(parameterType, property, javaType, jdbcType);//具体的枚举实体类型javaTypeClassTypeHandler<?> typeHandlerInstance = resolveTypeHandler(javaTypeClass, typeHandler);
//这里就将要创建类型的handlerprotected TypeHandler<?> resolveTypeHandler(Class<?> javaType, Class<? extends TypeHandler<?>> typeHandlerType) {    if (typeHandlerType == null) {      return null;    }    // javaType ignored for injected handlers see issue #746 for full detail    TypeHandler<?> handler = typeHandlerRegistry.getMappingTypeHandler(typeHandlerType);    if (handler == null) {      // not in registry, create a new one      handler = typeHandlerRegistry.getInstance(javaType, typeHandlerType);    }    return handler;  }//获得对应的枚举的handlerpublic <T> TypeHandler<T> getInstance(Class<?> javaTypeClass, Class<?> typeHandlerClass) {    if (javaTypeClass != null) {      try {       //主要是这里。我们获得handler的构造器,构造器传递枚举类型的参数        Constructor<?> c = typeHandlerClass.getConstructor(Class.class);        return (TypeHandler<T>) c.newInstance(javaTypeClass);      } catch (NoSuchMethodException ignored) {        // ignored      } catch (Exception e) {        throw new TypeException("Failed invoking constructor for handler " + typeHandlerClass, e);      }    }    try {     //如果是空的构造器就直接返回默认的构造器。      Constructor<?> c = typeHandlerClass.getConstructor();      return (TypeHandler<T>) c.newInstance();    } catch (Exception e) {      throw new TypeException("Unable to find a usable constructor for " + typeHandlerClass, e);    }  }

希望能帮到大家理解。如果有什么问题可以及时沟通。至于使用在网上很多。只是解释一下mybatis的handler的疑问。有什么好的想法可以留言共同探讨一下。

原创粉丝点击