mybatis入库的Handler解读

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

解读过程

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

@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);
//具体的枚举实体类型javaTypeClass
TypeHandler<?> typeHandlerInstance = resolveTypeHandler(javaTypeClass, typeHandler);
//这里就将要创建类型的handler
protected 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;
  }
//获得对应的枚举的handler
public <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);
    }
  }
//sql在执行时候的处理类BaseStatementHandler
//创建参数的默认Handler
XMLLanguageDriver.createParameterHandler()
//DefaultParameterHandler TypeHandlerRegistry在获得默认注册的handler时候就是基本类型的zhuangh
this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();

这里写图片描述

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青0721松

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值