码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • MybatisPlus 处理保存实体对象时,对于枚举类型的数据库存储问题


    MybatisPlus 处理保存实体对象时,对于枚举类型的数据库存储问题以及解决 @EnumValue 失效问题

    • 1. 前言
      • 1.1 先看问题代码
      • 1.2 存在的问题
    • 2. 解决前言问题(自定义)
      • 2.1 自定义枚举转换器
      • 2.2 附源码:
      • 2.3. 参考
    • 3. 解决 上述 @EnumValue 失效问题
      • 3.1 首先,配置文件
      • 3.2 实现效果的方式
        • 3.2.1 使用 @EnumValue 注解
        • 3.2.2 使用 implements IEnum
      • 3.3 注意实体
      • 3.4 测试看效果
        • 3.4.1 插入数据
        • 3.4.2 查询数据
        • 3.4.3 插入数据(前端实体)
      • 3.5 关于检索查询的问题
        • 3.5.1 先看问题
        • 3.5.2 问题所在(IEnum[Integer] 与 IEnum[String]的不同)
      • 3.6 官网详解
    • 4. 推荐 Mybatis、MybatisPlus 其他相关问题的文章

    1. 前言

    1.1 先看问题代码

    • 如下:
    • 枚举类:
      在这里插入图片描述
    • 实体:
      用自带的枚举解析器:
      @TableField(typeHandler = EnumTypeHandler.class)
      
      • 1
      在这里插入图片描述
    • service 里:(通过mybatisPlus自带方法保存对象)
      在这里插入图片描述

    1.2 存在的问题

    • 发现问题,如下:
      数据库存的不是我想要的枚举的key,想存 1 和 2,这种方式没有实现
      在这里插入图片描述
      在这里插入图片描述
    • 所以需自己写枚举转换器

    2. 解决前言问题(自定义)

    2.1 自定义枚举转换器

    • 看代码:
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      核心代码还是看下面源码吧
    • 看效果:
      在这里插入图片描述
      问题解决

    2.2 附源码:

    1. MyBaseEnum.java
      package com.liu.susu.enums.handler;
      
      /**
       * description
       *
       * @author susu
       * @date 2022-12-01
       **/
      public interface MyBaseEnum {
      
          Object getCode();
      
          String getDesc();
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    2. ValueEnumTypeHandler.java
      package com.liu.susu.enums.handler;
      
      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;
      
      /**
       * 值枚举转换处理器
       * @param  枚举类型
       */
      @MappedTypes({MyBaseEnum.class})
      public class ValueEnumTypeHandler<E extends Enum<?> & MyBaseEnum> extends BaseTypeHandler<MyBaseEnum> {
      
          private Class<E> type;
      
          public ValueEnumTypeHandler(Class<E> type) {
              if (type == null) {
                  throw new IllegalArgumentException("Type argument cannot be null");
              }
              this.type = type;
          }
      
          @Override
          public void setNonNullParameter(PreparedStatement ps, int i, MyBaseEnum parameter, JdbcType jdbcType)
                  throws SQLException {
      //        ps.setInt(i, parameter.getCode());
              ps.setObject(i, parameter.getCode());
          }
      
          @Override
          public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
              int code = rs.getInt(columnName);
              return rs.wasNull() ? null : codeOf(code);
          }
      
          @Override
          public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
              int code = rs.getInt(columnIndex);
              return rs.wasNull() ? null : codeOf(code);
          }
      
          @Override
          public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
              int code = cs.getInt(columnIndex);
              return cs.wasNull() ? null : codeOf(code);
          }
      
          private E codeOf(int code){
              try {
                  return codeOf(type, code);
              } catch (Exception ex) {
                  throw new IllegalArgumentException("Cannot convert" + code + "to" + type.getSimpleName() + "by code value.", ex);
              }
          }
      
          private static <E extends Enum<?> & MyBaseEnum> E codeOf(Class<E> enumClass, Object code) {
              E[] enumConstants = enumClass.getEnumConstants();
              for (E e : enumConstants) {
                  if (e.getCode() == code) {
                      return e;
                  }
              }
              return null;
          }
      
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
    3. SexEnum.java
      在这里插入图片描述
      package com.liu.susu.enums;
      
      import com.baomidou.mybatisplus.annotation.EnumValue;
      import com.liu.susu.enums.handler.MyBaseEnum;
      
      public enum SexEnum implements MyBaseEnum {
      
          BOY("1","男孩"),
          GIRL("2","女孩");
      
      //    @EnumValue
          private String code;
          private String desc;
      
          SexEnum(String code, String desc) {
              this.code = code;
              this.desc = desc;
          }
      
          @Override
          public String getCode() {
              return this.code;
          }
      
          @Override
          public String getDesc() {
              return this.desc;
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
    4. 实体(实体里要注意换成ValueEnumTypeHandler):
      @TableField(typeHandler = ValueEnumTypeHandler.class)
          private SexEnum sex;
      
      • 1
      • 2
      在这里插入图片描述

    2.3. 参考

    • 上述源码参考文章地址:
      基于 SpringBoot+MybatisPlus+Jackson 优雅使用枚举值的方案.

    3. 解决 上述 @EnumValue 失效问题

    • 上面自定义虽然解决问题了,但是略显麻烦,既然有简单的方法肯定还是想用简单的,就是想解决问题就失效了呢?继续往下看吧

    3.1 首先,配置文件

    • 需要配置枚举的扫描包
      (其中 type-enums-package 也可用 typeEnumsPackage):
      mybatis-plus:
        type-aliases-package: com.liu.susu.*.entity
        type-enums-package: com.liu.susu.*.entity.enums;com.liu.susu.message.enums
      
      • 1
      • 2
      • 3
      在这里插入图片描述

    3.2 实现效果的方式

    3.2.1 使用 @EnumValue 注解

    • 代码如下:
      在这里插入图片描述
      package com.liu.susu.message.enums;
      
      import com.baomidou.mybatisplus.annotation.EnumValue;
      import com.fasterxml.jackson.annotation.JsonValue;
      
      public enum SexEnum {
          BOY("1", "男孩"),
          GIRL("2", "女孩");
      
          SexEnum(String code, String desc) {
              this.code = code;
              this.desc = desc;
          }
      
          @EnumValue //标注:存数据库里存 1 2
          private final String code;
      
          @JsonValue //给前端返回时用
          private final String desc;
      
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22

    3.2.2 使用 implements IEnum

    • 如下:
      在这里插入图片描述
      package com.liu.susu.message.enums;
      
      import com.baomidou.mybatisplus.annotation.IEnum;
      
      public enum ColourEnum implements IEnum<String> {
          BLACK("b", "黑色"),
          WHITE("w", "白色");
      
          private String value;
      
          private String name;
      
          ColourEnum(String value, String name) {
              this.value = value;
              this.name = name;
          }
      
          public String getValue() {
              return value;
          }
      
          public void setValue(String value) {
              this.value = value;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35

    3.3 注意实体

    • 不要使用 typeHandler = EnumTypeHandler.class!!!!,如下:
      在这里插入图片描述

    3.4 测试看效果

    3.4.1 插入数据

    • 代码如下:
      在这里插入图片描述
      在这里插入图片描述
    • 看效果:
      在这里插入图片描述

    3.4.2 查询数据

    1. 直接查询,如下:
      在这里插入图片描述
    2. 如果想展示数字code给前端,可以使用注解
      在这里插入图片描述
      在这里插入图片描述
      再看效果
      在这里插入图片描述

    3.4.3 插入数据(前端实体)

    • 需要注意,如果按照上面的加注解,反序列化需要注意可能会出问题,如下
      在这里插入图片描述

      在这里插入图片描述

    • 要解决上面的报错,很简单,前端也往后端传汉字就行了
      在这里插入图片描述
      在这里插入图片描述

    3.5 关于检索查询的问题

    3.5.1 先看问题

    1. 根据kind查询
      在这里插入图片描述
    2. 再根据colour查询,查无数据
      在这里插入图片描述
    3. 代码:
      在这里插入图片描述

    3.5.2 问题所在(IEnum[Integer] 与 IEnum[String]的不同)

    • 问题原因就是在定义枚举的时候指定的code的类型是不是Integer,如果是就可以用上述方式检索
      在这里插入图片描述
      在这里插入图片描述
    • 此问题待解释,为啥String的不行???
      • 好了,先介绍到这里吧,虽然遗留一个问题,但是相对还是既简单又省事,所以有空多看官网

    3.6 官网详解

    • 官网地址:
      https://baomidou.com/pages/8390a4/#.

    4. 推荐 Mybatis、MybatisPlus 其他相关问题的文章

    • 关于mybatis 枚举的其他问题可以看下面文章
      • Mysql + Mybatis 开发中的各种小问题
      • mybatis自定义枚举类型的转换器以及各种使用场景.
      • springBoot项目 ObjectMapper 序列化统一格式处理(含枚举问题)
      • 解决 LocalDateTime 的序列化与反序列化问题
      • springboot项目前后端分离:统一返回数据格式+mybatis 分页(含枚举格式统一)
      • MybatisPlus简单使用与自定义sql以及通过自定义sql实现多表联查的分页查询
      • 解决雪花算法id精度丢失问题(自定义序列化类将Set<Long> 转化成 Set<String>)
      • mybatis调用Oracle存储过程(给出无参、入参、出参调用等详细例子)——真的的保姆级别.
  • 相关阅读:
    shell之常用小工具(sort、uniq、tr、cut)
    Linux 部署 GitLab & idea 连接
    C语言牛客网(NowCoder)刷题篇
    载5-FU聚己内酯纳米粒子(5-FU-PCL-NP)|PCL-PEG-PCL载姜黄素纳米粒子|齐岳供应
    TailWind 使用指南
    设计模式:享元模式案例
    ubuntu访问github慢
    一种基于多尺度密集递归融合网络的图像超分辨率新算法
    力扣(LeetCode)754. 到达终点数字(C++)
    Oracle LiveLabs实验:8 Partitioning Techniques in Oracle Database
  • 原文地址:https://blog.csdn.net/suixinfeixiangfei/article/details/128130332
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号