MyBatis 查询映射自定义枚举

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Jerome_s/article/details/53965293
背景
        
        MyBatis查询若想映射枚举类型,则需要从 EnumTypeHandler 或者 EnumOrdinalTypeHandler 中选一个来使用
            1. EnumOrdinalTypeHandler  是按照序列来存取的,对应数据库的设计为 使用0开始按升序。
            2. EnumTypeHandler 是按照枚举的名字来存取的,对应数据库的设计为 直接使用枚举名。

       但是也有存在不是按0开始的,也不是按0升序的情况。上面两个都不满足我们的需求, 这时候又想使用枚举这就需要使用自定义枚举类。 

使用

        可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现         org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler

        我们可以为每个枚举类都写一个对应的handler,但是这样比较复杂,所以我们将每个需要映射到枚举的枚举类实现统一个一个枚举接口: IEnum.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 
  * @ClassName: IEnum 
  * @Description: 本系统所有枚举实现的接口 规范key value 用于MyBatis枚举映射
  * @author [email protected]
  * @date 2015年11月29日 下午9:29:35 
  *
  */
public  interface  IEnum {
     
     int  getKey();
     void  setKey( int  key);
 
     String getValue();
     void  setValue(String value);
}
        
        为这个接口统写一个handle: EnumKeyTypeHandler.java
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
 
  * @ClassName: EnumKeyTypeHandler 
  * @Description: 本系统所有枚举都是使用这个处理器将key定为存取的依据 
  * @author [email protected]
  * @date 2015年11月29日 下午9:34:14 
  * @see 参考源码EnumOrdinalTypeHandler/EnumTypeHandler
  * @see 参考 http://mybatis.org/mybatis-3/zh/configuration.html#typeHandlers
  *
  */
public  class  EnumKeyTypeHandler  extends  BaseTypeHandler<IEnum>{
     
     private  Class<IEnum> type;
     private  final  IEnum[] enums;
  
     /**
      * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
      * @param type 配置文件中设置的转换类
      */
     public  EnumKeyTypeHandler(Class<IEnum> type) {
         if  (type ==  null )
             throw  new  IllegalArgumentException( "Type argument cannot be null" );
         this .type = type;
         this .enums = type.getEnumConstants();
         if  ( this .enums ==  null )
             throw  new  IllegalArgumentException(type.getSimpleName()
                     " does not represent an enum type." );
     }
  
     @Override
     public  IEnum getNullableResult(ResultSet rs, String columnName)  throws  SQLException {
         // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
         int  i = rs.getInt(columnName);
          
         if  (rs.wasNull()) {
             return  null ;
         else  {
             // 根据数据库中的code值,定位IEnum子类
             return  locateIEnum(i);
         }
     }
  
     @Override
     public  IEnum getNullableResult(ResultSet rs,  int  columnIndex)  throws  SQLException {
         // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
         int  i = rs.getInt(columnIndex);
         if  (rs.wasNull()) {
             return  null ;
         else  {
             // 根据数据库中的code值,定位IEnum子类
             return  locateIEnum(i);
         }
     }
  
     public  IEnum getNullableResult(CallableStatement cs,  int  columnIndex)  throws  SQLException {
         // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
         int  i = cs.getInt(columnIndex);
         if  (cs.wasNull()) {
             return  null ;
         else  {
             // 根据数据库中的code值,定位IEnum子类
             return  locateIEnum(i);
         }
     }
  
     public  void  setNonNullParameter(PreparedStatement ps,  int  i, IEnum parameter, JdbcType jdbcType)
             throws  SQLException {
         // baseTypeHandler已经帮我们做了parameter的null判断
         ps.setInt(i, parameter.getKey());
  
     }
      
     /**
      * 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷
      * @param key 数据库中存储的自定义code属性
      * @return code对应的枚举类
      */
     private  IEnum locateIEnum( int  key) {
         for (IEnum status : enums) {
             if (status.getKey()== key) {
                 return  status;
             }
         }
         throw  new  IllegalArgumentException( "未知的枚举类型:"  + key +  ",请核对"  + type.getSimpleName());
     }
 
}

枚举类使用: SexEnum.java
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
/**
  * 性别枚举
 
  * @author [email protected]
  */
public  enum  SexEnum  implements  IEnum {
 
     MAN( 1 "男" ), WOMAN( 2 "女" );
 
     private  int  key;
     private  String value;
 
     private  SexEnum( int  key, String value) {
         this .key = key;
         this .value = value;
     }
 
     public  int  getKey() {
         return  key;
     }
 
     public  void  setKey( int  key) {
         this .key = key;
     }
 
     public  String getValue() {
         return  value;
     }
 
     public  void  setValue(String value) {
         this .value = value;
     }
}
dao
1
2
3
4
List<User> users = sqlSession.selectList( "UserMapper.selectUsers4Enum" );
for  (User u : users) {
     System.out.println(u.toString());
}
mapper
1
2
3
4
5
6
< resultMap  id = "selectUsers4EnumResultMap"  type = "User" >
   < result  property = "sex"  column = "sex"  javaType = "com.hqu.enums.SexEnum"  typeHandler = "com.hqu.enums.EnumKeyTypeHandler" />
</ resultMap >
< select  id = "selectUsers4Enum"  resultMap = "selectUsers4EnumResultMap" >
     SELECT * FROM t_user
</ select >
结果
1
2
3
4
User [ id =1, user_name=jerome100, age=26, sex=MAN, birthday=Sat Dec 31 00:00:00 CST 2016]
User [ id =3, user_name=jelly, age=25, sex=WOMAN, birthday=Sat Dec 31 00:00:00 CST 2016]
User [ id =4, user_name=jerome, age=26, sex=MAN, birthday=Sat Dec 31 00:00:00 CST 2016]
User [ id =5, user_name=jelly, age=25, sex=WOMAN, birthday=Sat Dec 31 00:00:00 CST 2016]

总结

        个人觉得有关MyBatis的插入查询更新等还是不用枚举的好因为会增加复杂度和代码量,使用数字代表的较为合理。


参考:

        1.  mybatis官方文档 
        3.  自定义枚举类参考
        4.  MyBatis官方手册

代码:

猜你喜欢

转载自blog.csdn.net/Jerome_s/article/details/53965293