springboot + mybatis 自定义枚举类型转换

MyBatis内置了两个枚举转换器分别是:org.apache.ibatis.type.EnumTypeHandler和org.apache.ibatis.type.EnumOrdinalTypeHandler。java

EnumTypeHandler是默认的枚举转换器,该转换器将枚举实例转换为实例名称的字符串。好比有个枚举数据库

NO_RECOVERY(10),使用EnumTypeHandler保存在数据库中的就是“NO_RECOVERY”

EnumOrdinalTypeHandler这个转换器将枚举实例的ordinal属性做为取值(从0依次取值)。仍是上面的例子用这种转换器保存在数据库中的值就是0。apache

 

  若是咱们想保存枚举自己所定义的code值呢?这就须要自定义一个类型转换器,自定义一个int类型保存在数据库,即insert时枚举转换为int型数据保存在数据库,select时数据库中的int值转换成实segmentfault

体类的枚举类型。mybatis

 

1、自定义公共父接口app

public interface BaseCodeEnum { int getCode(); }

 

2、改造枚举, 须要转换的枚举类实现BaseCodeEnum接口ide

public enum RecoverType implements BaseCodeEnum { NO_RECOVERY(10), RECOVERY(11), PROTECT(12); int value; RecoverType(int value){ this.value = value; } @Override public int getCode() { return value; } } public enum TunnelType implements BaseCodeEnum { TP("TP"), TE("TE"), RSVP("RSVP"); private String name; TunnelType(String value) { this.name = value; } public String getValue() { return name; } @Override public int getCode() { switch (name) { case "TP": return 1; case "TE": return 2;case "RSVP": return 3; default: break; } return 255; } }

 


3、 Enum的转换工具类工具

public class CodeEnumUtil { public static <E extends Enum<?> & BaseCodeEnum> E codeOf(Class<E> enumClass, int code) { E[] enumConstants = enumClass.getEnumConstants(); for (E e : enumConstants) { if (e.getCode() == code) return e; } return null; } } @MappedTypes({BaseCodeEnum.class}) public class CodeEnumTypeHandler<E extends Enum<?> & BaseCodeEnum> extends BaseTypeHandler<BaseCodeEnum> { private Class<E> type; public CodeEnumTypeHandler(Class<E> type) { if (type == null) { throw new IllegalArgumentException("Type argument cannot be null."); } this.type = type; } //用于定义设置参数时,该如何把Java类型的参数转换为对应的数据库类型
 @Override public void setNonNullParameter(PreparedStatement ps, int i, BaseCodeEnum parameter, JdbcType jdbcType) throws SQLException { ps.setInt(i, parameter.getCode()); } //用于定义经过字段名称获取字段数据时,如何把数据库类型转换为对应的Java类型
 @Override public E getNullableResult(ResultSet rs, String columnName) throws SQLException { int code = rs.getInt(columnName); return rs.wasNull() ? null : codeOf(code); } //用于定义经过字段索引获取字段数据时,如何把数据库类型转换为对应的Java类型
 @Override public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException { int code = rs.getInt(columnIndex); return rs.wasNull() ? null : codeOf(code); } //用定义调用存储过程后,如何把数据库类型转换为对应的Java类型
 @Override public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { int code = cs.getInt(columnIndex); return cs.wasNull() ? null : codeOf(code); } private E codeOf(int code){ try { return CodeEnumUtil.codeOf(type, code); } catch (Exception ex) { throw new IllegalArgumentException("Cannot convert " + code + " to " + type.getSimpleName() + " by code value.", ex); } } }

 

3、使用,有两种方法:this

第一种:
  a) MyBatis配置文件中定义typeHandler扫描包路径
    mybatis:
      ...
      type-handlers-package: com.test.enumconvert

  b) 在自定义的转换类上加上这个注解 @MappedTypes({BaseCodeEnum.class})spa

第二种:
  首先,第一种的配置都去掉,修改mapper.xml文件


  a) 实体类 -> 数据库
  insert时,在values中指定typeHandler,好比
  #{recoverType,jdbcType=INTEGER,typeHandler=com.test.enumconvert.CodeEnumTypeHandler}


  b) 数据库 -> 实体类
  select时,也要指定typeHandler,好比在resultMap中指定
  <arg column="recover_type" jdbcType="INTEGER" javaType="com.test.pojo.RecoverType" typeHandler="com.test.enumconvert.CodeEnumTypeHandler" />

 

参考:https://www.jianshu.com/p/c84549e0ee10          https://segmentfault.com/a/1190000010755321

相关文章
相关标签/搜索