在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处理枚举类的方案。我看大多数人也都是这样在用。然而,在实际项目中,我们会发现随着枚举类的增多,这样写起来会很繁琐。我看了一下网络上似乎也没人处理这种情况。那么,下一篇文章将针对这种情况进行处理。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持服务器之家!
原文链接:http://www.cnblogs.com/dongying/p/6410889.html