在Mybatis中,处理枚举类的TypeHandler有两个:

  1. EnumTypeHandler: 用于保存枚举名
  2. EnumOrdinalTypeHandler: 用于保存枚举的序号。

在实际项目中,以上往往不能满足我们的需求。

需求分析

枚举需要包含两个属性,label(用于显示), value(实际的枚举值)。数据库保存枚举值(value)。

这很明显Mybatis提供的两个枚举TypeHandler不能满足我们的需求。此时,我们可以自定义一个通用的枚举TypeHandler来满足我们的需求。

自定义枚举TypeHandler

通用枚举DisplayedEnum

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接口,就可以:

  1. 通过getValue()获取枚举值。
  2. 通过getLabel()获取枚举的label属性。
  3. 通过valueOfEnum()将Integer值转换为指定的枚举类型。

普通枚举类

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

@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。示例如下:

<resultMap id="xxx" type="xxx">
...
<result column="type" jdbcType="TINYINT" property="type" typeHandler="xxx.xxx.xxx.DefaultEnumTypeHandler" />
...
</resultMap>

即我们需要通过使用typeHandler来指定。

小结

以上是我们应用在实际项目中的一个对于Mybatis处理枚举类的方案。我看大多数人也都是这样在用。然而,在实际项目中,我们会发现随着枚举类的增多,这样写起来会很繁琐。我看了一下网络上似乎也没人处理这种情况。那么,下一篇文章将针对这种情况进行处理。

转自:https://javafan.cn/2017/02/16/mybatis_typehandler/

Mybatis之XML使用Enum枚举传递数据的更多相关文章

  1. OpenCV和Matlab 通过XML传递数据

    因为现在下到的数据集大部分都使用了Matlab的Calibration toolbox 进行标定,其结构大部分是.mat结构的,所以它和opencv中数据传递需要一个中间过程,网上也有直接调用matl ...

  2. 【mybatis xml】数据层框架应用--Mybatis 基于XML映射文件实现数据的CRUD

    使用MyBatis框架进行持久层开发 MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架. MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索. MyBa ...

  3. Mybatis系列全解(四):全网最全!Mybatis配置文件XML全貌详解

    封面:洛小汐 作者:潘潘 做大事和做小事的难度是一样的.两者都会消耗你的时间和精力,所以如果决心做事,就要做大事,要确保你的梦想值得追求,未来的收获可以配得上你的努力. 前言 上一篇文章 <My ...

  4. mybatis Mapper XML 文件

    MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% ...

  5. MyBatis 的 XML 映射文件使用说明

    简介 文档参考地址:http://www.mybatis.org/mybatis-3/zh/index.html MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器 ...

  6. SpringBoot整合Mybatis之xml

    SpringBoot整合Mybatis mybatis ORM框架.几个重要的概念: Mapper配置 : 可以使用基于XML的Mapper配置文件来实现,也可以使用基于Java注解的Mybatis注 ...

  7. MyBatis——Mapper XML 文件

    Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会 ...

  8. MyBatis Mapper XML 文件 的学习详解

    MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JDBC 代码来比较,你会发现映射文件节省了大约 ...

  9. MyBatis Mapper XML 详解

    MyBatis Mapper XML 详解 MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JD ...

随机推荐

  1. Java解析Json数据的两种方式

    JSON数据解析的有点在于他的体积小,在网络上传输的时候可以更省流量,所以使用越来越广泛,下面介绍使用JsonObject和JsonArray的两种方式解析Json数据. 使用以上两种方式解析json ...

  2. phpstudy2017版本的nginx 支持laravel 5.X配置

    之前做开发和学习一直用phpstudy的mysql服务,确实很方便,开箱即用.QQ群交流:697028234 现在分享一下最新版本的phpstudy2017 laravel环境配置. 最新版的phps ...

  3. Sub-process /usr/bin/dpkg returned an error code (1)解决方法

    在ubuntu下使用apt-get install 安装资源的时候,总是会遇到Sub-process /usr/bin/dpkg returned an error code (1) 错了, 跟安装软 ...

  4. 《转》深入理解Activity启动流程(三)–Activity启动的详细流程2

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...

  5. linux提权辅助工具(三):privchecker.py

    来自:https://www.securitysift.com/download/linuxprivchecker.py #!/usr/env python ##################### ...

  6. New Concept English Two 19 49

    $课文47 嗜酒的鬼魂 481. A public house which was recently bought by Mr.Ian Thompson is up for sale. 伊恩.汤普森先 ...

  7. iOS-----使用AddressBook管理联系人

    使用AddressBook管理联系人 iPhone手机通常都是自带的Contacts应用,包括所有联系人的性(last name).名(first name).电话.E-mail地址.住址.生日等各种 ...

  8. linux screen 命令详解(转载)

    转载于:http://www.cnblogs.com/mchina/archive/2013/01/30/2880680.html 一.背景 系统管理员经常需要SSH 或者telent 远程登录到Li ...

  9. 【传输协议】https SSL主流数字证书都有哪些格式?

    一般来说,主流的Web服务软件,通常都基于两种基础密码库:OpenSSL和Java. Tomcat.Weblogic.JBoss等,使用Java提供的密码库.通过Java的Keytool工具,生成Ja ...

  10. test20181015 B 君的第三题

    题意 B 君的第三题(zhengzhou) 题目描述 让你在战争和耻辱中做一块选择,你选择耻辱,可你将来还得进行战争. 在平面上有n 个整点(横纵坐标都是整数) B 君想找到一个整点,使得这个点,到所 ...