自定义Mapper 枚举处理器 IllegalArgumentException: No enum constant .... 的解决办法

1.定义通用枚举接口

public interface BaseEnum, T> {
    /**
     * 获取枚举值
     *
     * @return 枚举值
     */
    T getValue();
}

2.具体的枚举实现通用接口

public enum UserStatusEnum implements BaseEnum {
    /**
     * 未激活
     */
    NOT_ACTIVE(0),
    /**
     * 正常
     */
    NORMAL(1),
    /**
     * 冻结
     */
    FROZEN(2),
    /**
     * 封禁
     */
    BLOCK(3);

    private Integer value;

    UserStatusEnum(Integer value) {
        this.value = value;
    }

    @Override
    public Integer getValue() {
        return value;
    }
}

3.数据库存储类型

 

 

4.编写枚举类型处理器,

注意

@MappedTypes({UserStatusEnum.class})

注解,该注解必须在该处理器(及其子类)上,参数是要具体处理的枚举Class对象

在多模块在开发中,当系统依赖中已经存在相关的处理器,可以写一个子类,继承它,覆写其中的必要方法,无需重新写一个处理器

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

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author
 * @version 1.0
 * @since 2019/2/27 下午 05:49
 */
@MappedTypes({UserStatusEnum.class})
public  class BaseEnumTypeHandler & BaseEnum> extends BaseTypeHandler {
    /**
     * 枚举的class
     */
    private Class type;
    /**
     * 枚举的每个元素
     */
    private E[] enums;

    private Map enumMap;

    public BaseEnumTypeHandler() {
    }

    /**
     * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
     *
     * @param type 配置文件中设置的转换类
     */
    public BaseEnumTypeHandler(Class type) {
        this.type = type;
        this.enums = type.getEnumConstants();
        enumMap = new HashMap<>(enums.length);
        for (E e : enums) {
            enumMap.put(Objects.toString(e.getValue()), e);
        }

    }

    /**
     * 用于定义设置参数时,该如何把Java类型的参数转换为对应的数据库类型;
     *
     * @param ps
     * @param i
     * @param parameter
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter,
                                    JdbcType jdbcType) throws SQLException {
        /*
         * BaseTypeHandler已经帮我们做了parameter的null判断
         * 数据库存储的是枚举的值,所以我们这里使用 value , 如果需要存储 name,可以自定义修改
         */
        if (jdbcType == null) {
            ps.setObject(i, parameter.getValue());
        } else {
            ps.setObject(i, parameter.getValue(), jdbcType.TYPE_CODE);
        }
    }

    /**
     * 用于定义通过字段名称获取字段数据时,如何把数据库类型转换为对应的Java类型
     *
     * @param rs
     * @param columnName
     * @return
     * @throws SQLException
     */
    @Override
    public E getNullableResult(ResultSet rs, String columnName)
            throws SQLException {
        String i = rs.getString(columnName);
        return rs.wasNull() ? null : enumMap.get(i);
    }

    /**
     * 用于定义通过字段索引获取字段数据时,如何把数据库类型转换为对应的Java类型;
     *
     * @param rs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public E getNullableResult(ResultSet rs, int columnIndex)
            throws SQLException {
        String i = rs.getString(columnIndex);
        return rs.wasNull() ? null : enumMap.get(i);
    }

    /**
     * 用定义调用存储过程后,如何把数据库类型转换为对应的Java类型
     *
     * @param cs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex)
            throws SQLException {
        String i = cs.getString(columnIndex);
        return cs.wasNull() ? null : enumMap.get(i);
    }
}

 

5.配置文件

添加配置type-handlers-package,指向处理器的包名位置

该配置项  位于(mybatis或mybatis-plus)下

mybatis-plus:
  mapper-locations: classpath:/cn/edu/*/xml/*Mapper.xml
  type-aliases-package: cn.edu.model
  type-aliases-super-type: cn.edu.model.BaseModel
  global-config:
    db-config:
      field-strategy: ignored
      #全局默认主键类型
      id-type: id_worker
      # 逻辑已删除值
      logic-delete-value: 1
      # 逻辑未删除值
      logic-not-delete-value: 0
      # 数据库类型
      db-type: mysql
    #缓存sql解析
    sql-parser-cache: true
  configuration:
    # sql执行语句打印
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    #自动驼峰命名规则
    map-underscore-to-camel-case: true
  #自定义类型处理器的包名
  type-handlers-package: cn.edu.handler

 

结束语:

然后从数据读取数据就可以转换到对应的枚举,而不会报错 

java.lang.IllegalArgumentException: No enum constant     包名.UserStatusEnum.1

 

参考:http://www.cnblogs.com/qnight/p/8997496.html

         https://blog.csdn.net/u014044812/article/details/78258730

你可能感兴趣的:(JAVAEE)