mybatis处理枚举与数据库照应

119 阅读1分钟

EnumTypeHandler

EnumTypeHandler使用的是枚举的名字

image.png

自定义TypeHandler处理枚举类型

枚举类

  /** 等待审批 */
  WAITING(4, "待审批"), NORMAL(1, "正常"),  
  ABNORMAL(2, "异常"), 
  /** 暂停 */ 
  PAUSE(3, "暂停"), 
  /** 单次完成 **/ 
  COMPLETE(5, "完成"), RUNNING(6, "执行中"), REJECT(7, "已拒绝") , EXPIRE(8 , "失效" ), QUEUING(9 , "排队中" );

//  public static final List<OptionVO> OPTION_VOS =
//      Arrays.stream(values())
//          .map(status -> {
//            return OptionVO.of(status.name() ,  status.dbData() );
//          } )
//          .collect(Collectors.toList());

  public static Integer getDbDataByName(String name){

    for(VssStatus status :values()){
          if(status.name().equals(name))
            return status.dbData();
    }
    return null;
  }

  public final int dbData;
  private final String label;

  VssStatus(int dbData, String label) {
    this.dbData = dbData;
    this.label = label;
  }

  @Override
  public int dbData() {
    return dbData;
  }

  public String getLabel() {
    return label;
  }
}

/**   , 仅支持枚举实现 */
public interface DbEnum {
  int dbData();
}

类型处理器

@Slf4j
public class DbEnumTypeHandler<E extends DbEnum> extends BaseTypeHandler<E> {
  private final Class<E> type;
  private final E[] enumConstants;

  public DbEnumTypeHandler(Class<E> type) {
    if (type == null) throw new IllegalArgumentException("Type argument cannot be null");
    this.type = type;
    this.enumConstants = type.getEnumConstants();
  }

  @Override   //定义当前数据如何保存到数据库
  public void setNonNullParameter(PreparedStatement ps, int i, DbEnum parameter, JdbcType jdbcType)
      throws SQLException {
    ps.setInt(i, parameter.dbData());
  }

  @Override    // 需要根据从数据库中拿到的枚举类型的状态码返回一个枚举对象
  public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
    int dbData = rs.getInt(columnName);
    if (rs.wasNull()) {
      return null;
    }
    return getEnum(dbData);
  }

  private E getEnum(int dbData) {
    if (enumConstants == null) {
      log.warn("DbEnum的实现类必须是枚举,但发现不为枚举!");
      return null;
    }

    for (E enumConstant : enumConstants) {
      if (enumConstant.dbData() == dbData) {
        return enumConstant;
      }
    }

    return null;
  }

  @Override       
  public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    int dbData = rs.getInt(columnIndex);
    if (rs.wasNull()) {
      return null;
    }
    return getEnum(dbData);
  }

  @Override
  public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    int dbData = cs.getInt(columnIndex);
    if (cs.wasNull()) {
      return null;
    }
    return getEnum(dbData);
  }
}

配置 在全局配置文件中,添加如下代码:

<typeHandlers>
    <typeHandler
        handler="com.shen.mybaties.typehandler.MyEnumEmpStatusTypeHandler"
        javaType="com.shen.mybaties.bean.EmpStatus" />
</typeHandlers>

(1)全局配置文件中配置全局的类型处理器 (2)也可以在处理某个字段的时候告诉MyBatis用什么类型处理器

本文参考文档:
MyBatis学习笔记——自定义TypeHandler(处理枚举)
SpringBoot Mybatis EnumTypeHandler自定义统一处理器