背景
        
        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 jerome_s@qq.com
 * @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 jerome_s@qq.com
 * @date 2015年11月29日 下午9:34:14 
 * @see 参考源码EnumOrdinalTypeHandler/EnumTypeHandler
 *
 */
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 jerome_s@qq.com
 */
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官方手册

代码:

MyBatis 查询映射自定义枚举的更多相关文章

  1. mybatis-枚举类型的typeHandler&自定义枚举类型typeHandler

    MyBatis内部提供了两个转化枚举类型的typeHandler给我们使用. org.apache.ibatis.type.EnumTypeHandler 是使用枚举字符串名称作为参数传递的 org. ...

  2. Spring Boot入门系列(十七)整合Mybatis,创建自定义mapper 实现多表关联查询!

    之前讲了Springboot整合Mybatis,介绍了如何自动生成pojo实体类.mapper类和对应的mapper.xml 文件,并实现最基本的增删改查功能.mybatis 插件自动生成的mappe ...

  3. 【转载】Mybatis多参数查询映射

    转载地址:http://www.07net01.com/zhishi/402787.html 最近在做一个Mybatis的项目,由于是接触不久,虽然看了一下资料,但在实际开发中还是暴 露了很多问题,其 ...

  4. Mybatis实战之自定义TypeHandler处理枚举

    在Mybatis中,处理枚举类的TypeHandler有两个: EnumTypeHandler: 用于保存枚举名 EnumOrdinalTypeHandler: 用于保存枚举的序号. 在实际项目中,以 ...

  5. 学习Spring Boot:(十二)Mybatis 中自定义枚举转换器

    前言 在 Spring Boot 中使用 Mybatis 中遇到了字段为枚举类型,数据库存储的是枚举的值,发现它不能自动装载. 解决 内置枚举转换器 MyBatis内置了两个枚举转换器分别是:org. ...

  6. AutoMapper在MVC中的运用03-字典集合、枚举映射,自定义解析器

    本篇AutoMapper使用场景: ※ 源字典集合转换成目标字典集合 ※ 枚举映射 ※ 自定义解析器 ※ 源中的复杂属性和Get...方法转换成目标属性 源字典集合转换成目标字典集合 □ Domain ...

  7. mybatis自定义枚举转换类

    转载自:http://my.oschina.net/SEyanlei/blog/188919 mybatis提供了EnumTypeHandler和EnumOrdinalTypeHandler完成枚举类 ...

  8. mybatis 高级映射和spring整合之查询缓存(5)

    mybatis 高级映射和spring整合之查询缓存(5) 2.0 查询缓存 2.0.1 什么是查询缓存 mybatis提供缓存,用于减轻数据压力,提高数据库性能. mybatis提供一级缓存和二级缓 ...

  9. Mybatis sql映射文件浅析 Mybatis简介(三)

    简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML为载体映射SQL 之前提到过,各项配置信息将Mybatis应用的整 ...

随机推荐

  1. Python无法导入Cython的.pyx文件

    在import 相应包之前, 添加: import pyximport pyximport.install() 即可.

  2. github git 在GitHub上创建项目并将本地项目push到网站上

    众所周知,git是与svn类似的版本控制系统,git的去中心化.分布式等的优点,在不久将来用户量大有可能超过svn, 常见的代码托管网站有GitHub,coding.net, gitee.com 码云 ...

  3. JavaScript 递归

    递归是一种解决问题的方法,它解决问题的各个小部分,直到解决最初的大问题.通常涉及 函数调用自身. 能够像下面这样直接调用自身的方法或函数,是递归函数: var recursiveFunction = ...

  4. [LeetCode] Maximum Vacation Days 最大化休假日

    LeetCode wants to give one of its best employees the option to travel among N cities to collect algo ...

  5. [原创]手把手教你写网络爬虫(5):PhantomJS实战

    手把手教你写网络爬虫(5) 作者:拓海 摘要:从零开始写爬虫,初学者的速成指南! 封面: 大家好!从今天开始,我要与大家一起打造一个属于我们自己的分布式爬虫平台,同时也会对涉及到的技术进行详细介绍.大 ...

  6. Shiro整合Spring

    首先需要添加shiro的spring整合包. 要想在WEB应用中整合Spring和Shiro的话,首先需要添加一个由spring代理的过滤器如下: <!-- The filter-name ma ...

  7. pytorch 移动端框架 thnets 附c示例代码

    前年年前做一个手机移动端图像识别项目的时候, 先后尝试了mxnet,thnets,caffe,tensorflow. 当时的情况是,mxnet内存管理奇差,内存经常由于模型运算分配不足,app挂掉. ...

  8. [HNOI2011]赛车游戏

    题目描述 名歌手LAALA最近迷上了一款赛车游戏,游戏中开车的玩家在不同的路段需要选择不同的速度,使得自己在最短的时间内到达终点.开始游戏时,车内的初始油量为f,所以游戏的关键是如何在速度和耗油量之间 ...

  9. [SDOI2010]地精部落

    题目描述 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为N的山脉H可分为从左到右的N段,每段有一个[b][u]独一无二[/u][/b]的高度Hi, ...

  10. [HNOI2005]狡猾的商人

    题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要你判断.每组数据的第一行为两个正整数n和m, ...