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