在Mybatis中,處理枚舉類的TypeHandler有兩個:
- EnumTypeHandler: 用于保存枚舉名
- EnumOrdinalTypeHandler: 用于保存枚舉的序號。
在實際項目中,以上往往不能滿足我們的需求。
需求分析
枚舉需要包含兩個屬性,label(用于顯示), value(實際的枚舉值)。數據庫保存枚舉值(value)。
這很明顯Mybatis提供的兩個枚舉TypeHandler不能滿足我們的需求。此時,我們可以自定義一個通用的枚舉TypeHandler來滿足我們的需求。
自定義枚舉TypeHandler
通用枚舉DisplayedEnum
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public interface DisplayedEnum { String DEFAULT_VALUE_NAME = "value" ; String DEFAULT_LABEL_NAME = "label" ; default Integer getValue() { Field field = ReflectionUtils.findField( this .getClass(), DEFAULT_VALUE_NAME); if (field == null ) return null ; try { field.setAccessible( true ); return Integer.parseInt(field.get( this ).toString()); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } @JsonValue default String getLabel() { Field field = ReflectionUtils.findField( this .getClass(), DEFAULT_LABEL_NAME); if (field == null ) return null ; try { field.setAccessible( true ); return field.get( this ).toString(); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } static <T extends Enum<T>> T valueOfEnum(Class<T> enumClass, Integer value) { if (value == null ) throw new IllegalArgumentException( "DisplayedEnum value should not be null" ); if (enumClass.isAssignableFrom(DisplayedEnum. class )) throw new IllegalArgumentException( "illegal DisplayedEnum type" ); T[] enums = enumClass.getEnumConstants(); for (T t: enums) { DisplayedEnum displayedEnum = (DisplayedEnum)t; if (displayedEnum.getValue().equals(value)) return (T) displayedEnum; } throw new IllegalArgumentException( "cannot parse integer: " + value + " to " + enumClass.getName()); } } |
說明:
普通枚舉類通過實現DisplayedEnum接口,就可以:
- 通過getValue()獲取枚舉值。
- 通過getLabel()獲取枚舉的label屬性。
- 通過valueOfEnum()將Integer值轉換為指定的枚舉類型。
普通枚舉類
1
2
3
4
5
6
7
8
9
|
public enum CommonsType implements DisplayedEnum { NORMAL( "正常" , 0 ), INVALID( "無效" , 1 ); String label; Integer value; private CommonsType(String label, Integer value) { this .label = label; this .value = value; } } |
以上就是一個普通枚舉類的示例。
自定義枚舉TypeHandler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
@MappedJdbcTypes (value = JdbcType.TINYINT, includeNullJdbcType = true ) public class DefaultEnumTypeHandler extends BaseTypeHandler<DisplayedEnum> { private Class<DisplayedEnum> type; public EnumTypeHandler(){}; public EnumTypeHandler(Class<DisplayedEnum> type) { if (type == null ) throw new IllegalArgumentException( "Type argument cannot be null" ); this .type = type; } @Override public void setNonNullParameter(PreparedStatement ps, int i, DisplayedEnum parameter, JdbcType jdbcType) throws SQLException { ps.setInt(i, parameter.getValue()); } @Override public DisplayedEnum getNullableResult(ResultSet rs, String columnName) throws SQLException { return convert(rs.getInt(columnName)); } @Override public DisplayedEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return convert(rs.getInt(columnIndex)); } @Override public DisplayedEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return convert(cs.getInt(columnIndex)); } private DisplayedEnum convert( int status){ DisplayedEnum[] objs = type.getEnumConstants(); for (DisplayedEnum em: objs){ if (em.getValue() == status){ return em; } } return null ; } } |
使用我們自定義的DefaultEnumTypeHandler
由于Mybatis默認在處理枚舉類型的時候會使用EnumTypeHandler(只保存及轉換枚舉類型的名字), 因此,我們需要手動指定使用DefaultEnumTypeHandler。示例如下:
1
2
3
4
5
|
<resultMap id= "xxx" type= "xxx" > ... <result column= "type" jdbcType= "TINYINT" property= "type" typeHandler= "xxx.xxx.xxx.DefaultEnumTypeHandler" /> ... </resultMap> |
即我們需要通過使用typeHandler來指定。
小結
以上是我們應用在實際項目中的一個對于Mybatis處理枚舉類的方案。我看大多數人也都是這樣在用。然而,在實際項目中,我們會發(fā)現隨著枚舉類的增多,這樣寫起來會很繁瑣。我看了一下網絡上似乎也沒人處理這種情況。那么,下一篇文章將針對這種情況進行處理。
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持服務器之家!
原文鏈接:http://www.cnblogs.com/dongying/p/6410889.html