mybatis处理枚举类的简单方法

mybatis自带对枚举的处理类

org.apache.ibatis.type.EnumOrdinalTypeHandler<E> :该类实现了枚举类型和Integer类型的相互转换。
但是给转换仅仅是将对应的枚举转换为其索引位置,也就是"ordinal()"方法获取到的值。对应自定义的int值,该类无能为力。

org.apache.ibatis.type.EnumTypeHandler<E> :该类实现了枚举类型和String类型的相互转换。
对于想将枚举在数据库中存储为对应的int值的情况,该类没办法实现。

基于以上mybatis提供的两个枚举处理类的能力有限,因此只能自己定义对枚举的转换了。

自定义mybatis的枚举处理类EnumValueTypeHandler

该类需要继承org.apache.ibatis.type.BaseTypeHandler<E> ,然后在重定义的方法中实现自有逻辑。

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.MappedTypes;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

/**
 * 处理实现了{@link EsnBaseEnum}接口的枚举类
 * @author followtry
 * @time 2016年8月16日 下午8:06:49
 * @since 2016年8月16日 下午8:06:49
 */
 //在 xml 中添加该 TypeHandler 时需要使用该注解
@MappedTypes(value = {
  QcListTypeEnum.class,
  SellingQcBizTypeEnum.class
})
public class EnumValueTypeHandler<E extends EsnBaseEnum> extends BaseTypeHandler<E> {

 private Class<E> type;

 private final E[] enums;

 public EnumValueTypeHandler(Class<E> 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 void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
  //获取非空的枚举的int值并设置到statement中
  ps.setInt(i, parameter.getValue());
 }

 @Override
 public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
  int i = rs.getInt(columnName);
  if (rs.wasNull()) {
   return null;
  } else {
   try {
    return getEnumByValue(i);
   } catch (Exception ex) {
    throw new IllegalArgumentException(
      "Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex);
   }
  }
 }

 /**
  * 通过枚举类型的int值,获取到对应的枚举类型
  * @author jingzz
  * @param i
  */
 protected E getEnumByValue(int i) {
  for (E e : enums) {
   if (e.getValue() == i) {
    return e;
   }
  }
  return null;
 }

 @Override
 public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  int i = rs.getInt(columnIndex);
  if (rs.wasNull()) {
   return null;
  } else {
   try {
    return getEnumByValue(i);
   } catch (Exception ex) {
    throw new IllegalArgumentException(
      "Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex);
   }
  }
 }

 @Override
 public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  int i = cs.getInt(columnIndex);
  if (cs.wasNull()) {
   return null;
  } else {
   try {
    return getEnumByValue(i);
   } catch (Exception ex) {
    throw new IllegalArgumentException(
      "Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex);
   }
  }
 }

}

该处理器是处理继承了EsnBaseEnum接口的枚举类,因为该接口中定义了获取自定义int值的方法。

如果在 mybatis 的 xml 中配置 该 typehandler,则需要添加注解@MappedTypes。在添加 typeHandler 注册时使用具体的实现类注册。

配置文件如下:

<typeAliases>
<!-- 为自定义的 TypeHandler 指定别名,在 sql 的 xml 中即可使用别名访问了 -->
  <typeAlias type="cn.followtry.mybatis.EnumValueTypeHandler" alias="enumValueTypeHandler"/>
</typeAliases>
<typeHandlers>
  <!--处理枚举的值转换-->
  <typeHandler handler="cn.followtry.mybatis.EnumValueTypeHandler"/>
</typeHandlers>

自定义的 Enum 需要实现的接口

/**
 * @author jingzz
 * @time 2016年8月17日 上午9:22:46
 * @since 2016年8月17日 上午9:22:46
 */
public interface EsnBaseEnum {

  public int getValue();
}

而实现了EsnBaseEnum的枚举示例如下:

/**
 * 同步的类型
 * @author jingzz
 * @time 2016年8月3日 上午11:13:06
 */
public enum SyncType implements EsnBaseEnum {

  DEPT(3),//部门
  PERSON(1);//人员

  private int value;

  private SyncType(int value) {

    this.value = value;
  }

  @Override
  public int getValue(){
    return this.value;
  }
}

只有在实现了EsnBaseEnum的接口,EnumValueTypeHandler才能通过接口的getValue方法获取到对应枚举的值。

到此,对于枚举的简单处理逻辑已经实现完成了,接下来就是如何配置来使用该自定义枚举处理逻辑

配置对枚举的处理

首先,mybatis中对于处理逻辑的设置是在sql的映射文件中,如EsnSyncLogMapper.xml。

关键的设置枚举处理的位置如下:

<resultMap id="BaseResultMap" type="com.test.dao.model.EsnSyncLog" >
  <id column="id" property="id" jdbcType="INTEGER" />
  <result column="sync_time" property="syncTime" jdbcType="TIMESTAMP" />
  <result column="total_num" property="totalNum" jdbcType="INTEGER" />
  <result column="success_total_num" property="successTotalNum" jdbcType="INTEGER" />
  <result column="type" property="type" typeHandler="com.test.common.EnumValueTypeHandler" />
  <result column="msg" property="msg" jdbcType="VARCHAR" />
 </resultMap>

其中type列设置了属性typeHandler,其值为自定义的枚举处理逻辑。

而在具体sql中也需要使用typeHandler属性,如:

 <if test="type != null" >
  #{type, typeHandler=com.test.common.EnumValueTypeHandler},
 </if>

在mybatis处理到该位置时,就会调用typeHandler指定的处理类来处理枚举类型。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • Mybatis中自定义TypeHandler处理枚举详解

    在Mybatis中,处理枚举类的TypeHandler有两个: EnumTypeHandler: 用于保存枚举名 EnumOrdinalTypeHandler: 用于保存枚举的序号. 在实际项目中,以上往往不能满足我们的需求. 需求分析 枚举需要包含两个属性,label(用于显示), value(实际的枚举值).数据库保存枚举值(value). 这很明显Mybatis提供的两个枚举TypeHandler不能满足我们的需求.此时,我们可以自定义一个通用的枚举TypeHandler来满足我们的需求.

  • mybatis中实现枚举自动转换方法详解

    前言 最近在工作中遇到一个问题,在设计数据库的时候,我们有时候会把表里的某个字段的值设置为数字或者为英文来表示他的一些特殊含义.就拿设置成数字来说,假如1对应是学生,2对应是教师,在Java里面定义成这样的枚举,但是一般使用mybatis查出来的话,我们想要让它自动装换成我们想要的枚举,不需要再手动根据数值去判断设置成我们想要的枚举.要是实现这样的效果,那么我们就要用到mybatis的BaseTypeHandler了. BaseTypeHandler介绍 让我们来看看要继承BaseTypeHan

  • MyBatis中如何优雅的使用枚举详解

    问题 本文主要给大家介绍的是关于MyBatis使用枚举的相关内容,我们在编码过程中,经常会遇到用某个数值来表示某种状态.类型或者阶段的情况,比如有这样一个枚举: public enum ComputerState { OPEN(10), //开启 CLOSE(11), //关闭 OFF_LINE(12), //离线 FAULT(200), //故障 UNKNOWN(255); //未知 private int code; ComputerState(int code) { this.code =

  • mybatis处理枚举类的简单方法

    mybatis自带对枚举的处理类 org.apache.ibatis.type.EnumOrdinalTypeHandler<E> :该类实现了枚举类型和Integer类型的相互转换. 但是给转换仅仅是将对应的枚举转换为其索引位置,也就是"ordinal()"方法获取到的值.对应自定义的int值,该类无能为力. org.apache.ibatis.type.EnumTypeHandler<E> :该类实现了枚举类型和String类型的相互转换. 对于想将枚举在数

  • java实现利用String类的简单方法读取xml文件中某个标签中的内容

    1.利用String类提供的indexOf()和substring()快速的获得某个文件中的特定内容 public static void main(String[] args) { // 测试某个词出现的位置 String reqMessage = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + "<in>" + "<head&g

  • 利用java反射机制实现自动调用类的简单方法

    1. 新建TestServlet类 package com.yanek.test; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.ht

  • 详解SpringMVC 自动封装枚举类的方法

    springmvc默认无法自动封装枚举类,解决方法如下: 1.枚举类 public enum GoodsPromoteEnum { /** * 0 精品 */ fine("精品",0), /** * 1 限时购 */ limit("限时购",1), /** * 2 特价 */ cheap("特价",2); private String value; private int index; private GoodsPromoteEnum(Strin

  • java 枚举类中的valueOf用法说明

    目录 枚举类中的valueOf用法 先创建一个BasicEnum的接口 创建一个枚举类实现BasicEnum接口 枚举类valueOf方法的疑问 枚举类中的valueOf用法 前言:今天遇到了一个枚举类的valueOf用法,遇到了一点问题,这里特例写一个demo来测试一下 先创建一个BasicEnum的接口 /** * @Author 徐志 * @date 2020/9/4 12:42 **/ public interface BasicEnum<L,V> { /** * get name *

  • Mybatis中实体类属性与数据列表间映射方法介绍

    Mybatis不像Hibernate中那么自动化,通过@Column注解或者直接使用实体类的属性名作为数据列名,而是需要自己指定实体类属性和 数据表中列名之间的映射关系,这一点让用惯了Hibernate的人很不习惯,所幸经过探索找到了建立映射关系的三种办法,其中总也有比较 简单的. 首先先定义一个实体类,如下: public class User implements Serializable { private Integer userId; private String userName;

  • ASP.Net Core中使用枚举类而不是枚举的方法

    前言: 我相信大家在编写代码时经常会遇到各种状态值,而且为了避免硬编码和代码中出现魔法数,通常我们都会定义一个枚举,来表示各种状态值,直到我看到Java中这样使用枚举,我再想C# 中可不可以这样写,今天就分享一下我的感悟. 一.通常我们是这样使用枚举的 (1)switch中使用枚举 public enum EmployeeType { Manager, Servant, AssistantToTheRegionalManager } public class Employee { public

  • java枚举类的属性、方法和构造方法应用实战

    本文实例讲述了java枚举类的属性.方法和构造方法应用.分享给大家供大家参考,具体如下: 一 点睛 枚举类也是一种类,只是它是一种比较特殊的类,因此它一样可以使用属性和方法. 枚举类通常应该设计成不可变类,也就说它的属性值不应该允许改变,这样会更安全,而且代码更加简洁.为此,我们应该将枚举类的属性都使用private final修饰. 一旦为枚举类显式定义了带参数的构造器,则列出枚举值时也必须对应地传入参数. 二 简单枚举类实战 1 代码 Gender.java public enum Gend

  • SpringBoot使用validation-api实现对枚举类参数校验的方法

    前言 之前写了一个博客是关于使用SpringBoot使用validation-api实现参数校验,当时使用的注解都是validation-api自带的注解只能完成对空值.长度等简单的校验,在我们日常的使用当中会遇到对参数是否在枚举值类的校验,针对这种情况我们怎么来实现呢? SpringBoot使用validation-api实现参数校验可参考我的博客:SpringBoot使用validation-api实现参数校验 正文 SpringBoot使用validation-api实现对枚举类参数校验

  • java 枚举类定义静态valueOf(java.lang.String)方法的问题及解决

    目录 问题的起因 猜测.分析 最终解决方案 枚举类Enum方法简介(valueof,value,ordinal) 我们应该注意到enum类型有如下的一些特征 了解了这些基本特性,我们来看看如何使用它们 问题的起因 起因来自于我对于java枚举类的无知. 我本来想定义这样一个枚举类: public enum MenuOptions { CHAT_ROOM("#1"), MENU("#0"), ERROR("#9999"); private Stri

随机推荐