最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

mybatis-plus3.0.1枚舉返回為null解決辦法

 更新時(shí)間:2020年12月23日 11:37:52   作者:SakuyaM  
這篇文章主要介紹了mybatis-plus3.0.1枚舉返回為null解決辦法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

mybatis-plus 3.0.1 枚舉返回為null解決辦法

2020-11-02 14:28:48
今天再次回到代碼里無(wú)意間看到,原來(lái)和mybatis-plus沒(méi)有關(guān)系!發(fā)生這個(gè)問(wèn)題的根本原因還是要看是否在對(duì)應(yīng)的Mapper.xml里指定了jdbcType。由于我使用了IDEA的代碼生成插件,所以沒(méi)有再進(jìn)一步去研究為什么返回的數(shù)據(jù)類(lèi)型會(huì)是以BigDecimal包裝的,就此鬧了個(gè)笑話。。

結(jié)論:枚舉類(lèi)用EnumValue注解修飾的數(shù)據(jù)類(lèi)型,例如是Integer,那么在Mapper.xml中的jdbcType需要修改為對(duì)應(yīng)類(lèi)型!

最好的解決辦法就是使用新版的mybatis-plus!

3.1.0版本后改變了mybatis原生的默認(rèn)行為,而3.1.2版本以下的枚舉處理類(lèi)依然是EnumTypeHandler。推測(cè)在3.1.2以上的版本應(yīng)該是不會(huì)出現(xiàn)這個(gè)問(wèn)題的。

項(xiàng)目環(huán)境:springboot + oracle + mybatis-plus

實(shí)體類(lèi)引用到的枚舉類(lèi),實(shí)現(xiàn) IEnum 接口:

package com.abc.common.model.enums;

import com.baomidou.mybatisplus.core.enums.IEnum;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;

@Getter
public enum FieldType implements IEnum<Integer> {
  NONE(-1, ""),
  NORMAL_INPUT(0, "文本"),
  BIG_INPUT(1, "多文本"),
  DATETIME(2, "日期時(shí)間"),
  DATE(3, "日期"),
  TIME(4, "時(shí)間"),
  UPLOAD(5, "文件上傳"),
  DICT(6, "字典");

  private final Integer value;

  @JsonValue
  private final String fieldType;

  private static final FieldType[] values = values();

  FieldType(Integer value, String fieldType) {
    this.value = value;
    this.fieldType = fieldType;
  }

  @JsonCreator
  public static FieldType valueOf(Integer value) {
    for (FieldType enu : values) {
      if (enu.getValue().equals(value)) {
        return enu;
      }
    }

    return null;
  }
}

mybatis-plus中關(guān)于枚舉類(lèi)的配置:

mybatis-plus:
 #其它配置...
 type-enums-package: com.abc.common.model.enums
 #在3.0.1版本下無(wú)法設(shè)置默認(rèn)的枚舉類(lèi)型處理
 #default-enum-type-handler: com.abc.service.handler.CustomizeEnumTypeHandler
 #其它配置...

前面說(shuō)過(guò)了,項(xiàng)目使用的是mybatis-plus 3.0.1,這里配置default-enum-type-handler是沒(méi)有作用的。至于為什么不更新,項(xiàng)目是多人協(xié)同開(kāi)發(fā)的,公司也不允許私自修改依賴(lài)包。

調(diào)用接口查詢時(shí)問(wèn)題出現(xiàn)了:

mybatis-plus查詢結(jié)果

日志說(shuō)明這個(gè)字段是有一個(gè)有效值的,并且查詢出來(lái)了。(FIELD_TYPE字段是NUMBER(1)類(lèi)型)

映射到實(shí)體類(lèi)

6對(duì)應(yīng)的枚舉值應(yīng)該是DICT,也就是字典類(lèi)型才對(duì),但是映射到實(shí)體類(lèi)時(shí)卻變成了NULL。

在我看了一下午的源碼以后發(fā)現(xiàn)了問(wèn)題的原因:
EnumTypeHandler.class:

package com.baomidou.mybatisplus.extension.handlers;

import com.baomidou.mybatisplus.core.enums.IEnum;
import com.baomidou.mybatisplus.core.toolkit.EnumUtils;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

public class EnumTypeHandler<E extends Enum<?> & IEnum> extends BaseTypeHandler<IEnum> {
  private Class<E> type;

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

  public void setNonNullParameter(PreparedStatement ps, int i, IEnum parameter, JdbcType jdbcType) throws SQLException {
    if (jdbcType == null) {
      ps.setObject(i, parameter.getValue());
    } else {
      ps.setObject(i, parameter.getValue(), jdbcType.TYPE_CODE);
    }

  }

  public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return null == rs.getString(columnName) && rs.wasNull() ? null : EnumUtils.valueOf(this.type, rs.getObject(columnName));
  }

  public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return null == rs.getString(columnIndex) && rs.wasNull() ? null : EnumUtils.valueOf(this.type, rs.getObject(columnIndex));
  }

  public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return null == cs.getString(columnIndex) && cs.wasNull() ? null : EnumUtils.valueOf(this.type, cs.getObject(columnIndex));
  }
}

這是mybatis-plus用來(lái)處理數(shù)值和枚舉類(lèi)之間關(guān)系的處理類(lèi)(這里如果枚舉類(lèi)是用@EnumValue來(lái)標(biāo)注數(shù)值的話,處理類(lèi)是相同包結(jié)構(gòu)下的EnumAnnotationTypeHandler.class,原理相同),可以看到在一些列判空后最后使用EnumUtils工具類(lèi)來(lái)決定返回枚舉類(lèi)里的哪個(gè)值。
EnumUtils.class

package com.baomidou.mybatisplus.core.toolkit;

import com.baomidou.mybatisplus.core.enums.IEnum;
import java.lang.reflect.Field;
import java.util.Objects;

public class EnumUtils {
  public EnumUtils() {
  }

  public static <E extends Enum<?> & IEnum> E valueOf(Class<E> enumClass, Object value) {
    E[] es = (Enum[])enumClass.getEnumConstants();
    Enum[] var3 = es;
    int var4 = es.length;

    for(int var5 = 0; var5 < var4; ++var5) {
      E e = var3[var5];
      if (Objects.equals(((IEnum)e).getValue(), value)) {
        return e;
      }
    }

    return null;
  }

  public static <E extends Enum<?>> E valueOf(Class<E> enumClass, Object value, Field enumField) {
    E[] es = (Enum[])enumClass.getEnumConstants();
    Enum[] var4 = es;
    int var5 = es.length;

    for(int var6 = 0; var6 < var5; ++var6) {
      Enum e = var4[var6];

      try {
        if (Objects.equals(enumField.get(e), value)) {
          return e;
        }
      } catch (IllegalAccessException var9) {
      }
    }

    return null;
  }
}

理解了源碼就發(fā)現(xiàn)了問(wèn)題所在了,讓這個(gè)EnumUtils返回null值的情況,大概是Objects.equals()判斷值是否相等時(shí),找不到這個(gè)枚舉類(lèi)里面有任何和查詢出來(lái)的值相同的值。

查詢出來(lái)的value類(lèi)型

原來(lái)oracle的NUMBER類(lèi)型在這個(gè)工具類(lèi)里處理的時(shí)候,默認(rèn)是BigDecimal類(lèi)型,而我們?cè)诿杜e類(lèi)里定義的是Integer類(lèi)型。

Objects.equals(Object a, Object b)

public static boolean equals(Object a, Object b) {
  return (a == b) || (a != null && a.equals(b));
}

所以在判斷是否邏輯一致的時(shí)候調(diào)用了Integer數(shù)值的equals方法,也就是

//false
log.info(new Integer(6).equals(new BigDecimal(6)));

解決辦法就很簡(jiǎn)單了,可以寫(xiě)一個(gè)Number的子類(lèi),重寫(xiě)一個(gè)業(yè)務(wù)邏輯一致的equals方法。當(dāng)然最快速直接的就是把枚舉類(lèi)里的Integer改成BigDecimal類(lèi)型。

修改后的枚舉類(lèi):

package com.abc.common.model.enums;

import com.baomidou.mybatisplus.core.enums.IEnum;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;

import java.math.BigDecimal;

/**
 * 字段類(lèi)型枚舉
 * @author huangsz
 * @version 1.0
 * @date 2020/10/22 11:01
 */
@Getter
public enum FieldType implements IEnum<BigDecimal> {
  NONE(new BigDecimal(-1), ""),
  NORMAL_INPUT(new BigDecimal(0), "文本"),
  BIG_INPUT(new BigDecimal(1), "多文本"),
  DATETIME(new BigDecimal(2), "日期時(shí)間"),
  DATE(new BigDecimal(3), "日期"),
  TIME(new BigDecimal(4), "時(shí)間"),
  UPLOAD(new BigDecimal(5), "文件上傳"),
  DICT(new BigDecimal(6), "字典");

  private final BigDecimal value;

  @JsonValue
  private final String fieldType;

  private static final FieldType[] values = values();

  FieldType(BigDecimal value, String fieldType) {
    this.value = value;
    this.fieldType = fieldType;
  }

  @JsonCreator
  public static FieldType valueOf(BigDecimal value) {
    for (FieldType enu : values) {
      if (enu.getValue().equals(value)) {
        return enu;
      }
    }
    return null;
  }
}

修改Integer為BigDecimal后

這回出現(xiàn)了,問(wèn)題解決

到此這篇關(guān)于mybatis-plus3.0.1枚舉返回為null解決辦法的文章就介紹到這了,更多相關(guān)mybatis-plus枚舉返回null內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • slf4j與jul、log4j1、log4j2、logback的集成原理

    slf4j與jul、log4j1、log4j2、logback的集成原理

    這篇文章主要介紹了slf4j與jul、log4j1、log4j2、logback的集成原理,以及通用日志框架與具體日志實(shí)現(xiàn)系統(tǒng)的機(jī)制機(jī)制介紹,包括依賴(lài)的jar包,jar沖突處理等
    2022-03-03
  • Java 編程之IO流資料詳細(xì)整理

    Java 編程之IO流資料詳細(xì)整理

    這篇文章主要介紹了Java 編程之IO流資料詳細(xì)整理的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 一文讀懂JavaWeb前后端數(shù)據(jù)交互

    一文讀懂JavaWeb前后端數(shù)據(jù)交互

    本文主要介紹了一文讀懂JavaWeb前后端數(shù)據(jù)交互,包括HTTP請(qǐng)求與響應(yīng)、JSON數(shù)據(jù)格式以及常用的數(shù)據(jù)傳輸技術(shù),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Java代碼實(shí)踐12306售票算法(二)

    Java代碼實(shí)踐12306售票算法(二)

    這篇文章主要介紹了Java代碼實(shí)踐12306售票算法(二)的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • 深入理解JVM之類(lèi)加載機(jī)制詳解

    深入理解JVM之類(lèi)加載機(jī)制詳解

    這篇文章主要介紹了深入理解JVM之類(lèi)加載機(jī)制,結(jié)合實(shí)例形式詳細(xì)分析了類(lèi)加載機(jī)制原理、過(guò)程及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • SpringBoot整合JPA方法及配置解析

    SpringBoot整合JPA方法及配置解析

    這篇文章主要介紹了SpringBoot整合JPA方法及配置過(guò)程,JPA是Java Persistence API的簡(jiǎn)稱(chēng),中文名Java持久層API,感興趣想要詳細(xì)了解可以參考下文
    2023-05-05
  • Java中Cookie和Session詳解及區(qū)別總結(jié)

    Java中Cookie和Session詳解及區(qū)別總結(jié)

    這篇文章主要介紹了Java中Cookie和Session詳解,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-06-06
  • 基于Java中throw和throws的區(qū)別(詳解)

    基于Java中throw和throws的區(qū)別(詳解)

    下面小編就為大家?guī)?lái)一篇基于Java中throw和throws的區(qū)別(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • SpringSecurity認(rèn)證流程詳解

    SpringSecurity認(rèn)證流程詳解

    這篇文章主要介紹了SpringSecurity認(rèn)證流程詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 淺談Java回收對(duì)象的標(biāo)記和對(duì)象的二次標(biāo)記過(guò)程

    淺談Java回收對(duì)象的標(biāo)記和對(duì)象的二次標(biāo)記過(guò)程

    這篇文章主要介紹了淺談Java回收對(duì)象的標(biāo)記和對(duì)象的二次標(biāo)記過(guò)程的相關(guān)內(nèi)容,小編覺(jué)得還是挺不錯(cuò)的,這里給大家分享一下,需要的朋友可以參考。
    2017-10-10

最新評(píng)論

青浦区| 青铜峡市| 毕节市| 临泽县| 白城市| 屏边| 榆树市| 宁化县| 虎林市| 兰西县| 镇平县| 噶尔县| 叶城县| 屯门区| 平利县| 靖西县| 师宗县| 杭锦后旗| 镇康县| 若羌县| 什邡市| 和顺县| 锦屏县| 石嘴山市| 涟源市| 鄂伦春自治旗| 长沙县| 四子王旗| 饶阳县| 永川市| 马边| 屏边| 吉隆县| 和田市| 缙云县| 淮安市| 枣阳市| 绥江县| 碌曲县| 蒲江县| 平武县|