背景
        
        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. Java面试题—初级(1)

    1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致. 2.Java有 ...

  2. html5的八大特性

    HTML5是用于取代1999年所制定的 HTML 4.01 和 XHTML 1.0 标准的 HTML [1](标准通用标记语言下的一个应用)标准版本:现在仍处于发展阶段,但大部分浏览器已经支持某些 H ...

  3. JavaWeb小项目(一)

    总结一下前段时间,在学了JSP.Servlet.JavaBean后,配合Tomcat服务器加上MySQl数据库搭的第一个简单网站. 前前后后,在学习了以上说的这些概念知识后,还进一步熟悉了整个搭建的流 ...

  4. Django REST framework+Vue 打造生鲜超市(八)

    九.个人中心功能开发 9.1.drf的api文档自动生成和 (1) url #drf文档,title自定义 path('docs',include_docs_urls(title='仙剑奇侠传')), ...

  5. 洛谷 P2590 [ZJOI2008]树的统计(树链剖分)

    题目描述一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...

  6. javaIO操作之字节输出流--OutputStream

    OutputStream /** * <li>输出单个字节:public abstract void write(int b) throws IOException ; * <li& ...

  7. volume 方式使用 Secret - 每天5分钟玩转 Docker 容器技术(157)

    Pod 可以通过 Volume 或者环境变量的方式使用 Secret,今天先学习 Volume 方式. Pod 的配置文件如下所示: ① 定义 volume foo,来源为 secret mysecr ...

  8. pymysql实现从a表过滤出有效信息添加至b表

    # Author: yeshengbao # -- coding: utf-8 -- # @Time : 2018/4/16 19:23 import pymysql # 创建连接 conn = py ...

  9. bzoj 2435: [Noi2011]道路修建

    Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1条双向道 ...

  10. 2015 多校联赛 ——HDU5348(搜索)

    Problem Description As we all kown, MZL hates the endless loop deeply, and he commands you to solve ...