Mybatis-Plus通用枚举功能 [MyBatis-Plus系列] - 第493篇

历史文章(文章累计490+)

《国内最全的Spring Boot系列之一》

《国内最全的Spring Boot系列之二》

《国内最全的Spring Boot系列之三》

《国内最全的Spring Boot系列之四》

《国内最全的Spring Boot系列之五》

《国内最全的Spring Boot系列之六》

SpringBoot集成MyBatis-Plus + MyBatis-Plus代码生成器[MP系列] - 第490篇

MyBatis-Plus主键生成策略[MyBatis-Plus系列] - 第491篇

MyBatis-Plus实现逻辑删除[MyBatis-Plus系列] - 492篇

悟纤:师傅,你觉得生命的本质是什么?

师傅:生命的本质是能量

师傅:喜怒哀乐都是能量

师傅:话语是能量的载体

师傅:平和的语气,合适的词语,都会安抚心灵。

师傅:如果话语太锋利了,就会影响对方的情绪和心情,也就是能量紊乱

悟纤:那两个人相处之道,不就是需要注意使用平和的语气和用合适的词语来表达了?

师傅:平和的语气能够让人听着很舒服,情绪不容易上头。

师傅:不同的词语虽然都能够表达清楚意思,但用合适的词语,听起来让人觉得舒服的词语进行表达,能够让人在心里上更加愿意去接受。

悟纤:听师傅一席话,胜读十年书。

导读

Hi,大家好,我是悟纤。过着爱谁谁的生活,活出不设限的人生。

通常在开发中,有这样的需求:枚举类型存入数据库存的是编码code,然而返回给前端的时候是名称name,我们每次入库的时候都要getCode()以及返回给前端的时候要getName(),很繁琐,并且字段属于那种枚举类型的可读性也不高

基于以上问题:我们会尝试着定制一些逻辑专门去处理,一般是自定义枚举转换器实现,然而mybatis-plus提供了优雅的实现方式。

一、枚举的使用场景和好处

在实际的使用当中,当某个对象或者某个属性,需要有多个可供选择的状态或者描述,例如人的性别支付的状态错误的类型等等,都可以使用枚举。

好处:

(1)可读性高, 易理解。

(2)统一参数类型,避免传参错误。

(3)线程安全,全局唯一,无法修改。

二、版本区别

Mybatis-Plus 不同的版本,通用枚举配置是不一样的,稍早一些的需要实现 IEnum 接口,并且需要在配置文件中配置 typeEnumsPackage 或者编写配置类,这难免有些复杂。

而 Mybatis-Plus 从 3.5.2 版本开始只需使用 @EnumValue 注解枚举属性,简单来说就是一个注解解决了一系列配置,本文也将讲解 @EnumValue 注解枚举属性这种方式!

三、通用枚举实战

接下来用具体的例子看一下mybatis-plus通用枚举的使用。

3.1定义枚举

3.1.1方式1:@EnumValue标注入库映射字段

使用注解@EnumValue定义存储到数据库的值:

package com.kfit.user.enums;import com.baomidou.mybatisplus.annotation.EnumValue;import com.fasterxml.jackson.annotation.JsonValue;/** * author:悟纤「公众号SpringBoot」 * date:2023/9/15 */public enum GradeEnum {    PRIMARY(1, "小学"),    SECONDORY(2, "中学"),    HIGH(3, "高中");    @EnumValue//标记数据库存的值是code    private final int code;    @JsonValue //标注该字段要开启自定义序列化返回值    private final String desc;    GradeEnum(int code, String desc) {        this.code = code;        this.desc = desc;    }}

说明:注解@JsonValue注解是开启序列化返回的值。

3.1.2方式2:枚举属性实现 IEnum 接口

实现接口IEnum定义存储到数据库的值:

package com.kfit.user.enums;import com.baomidou.mybatisplus.annotation.IEnum;import com.fasterxml.jackson.annotation.JsonValue;/** * author:悟纤「公众号SpringBoot」 * date:2023/9/15 */public enum AgeEnum implements IEnum<Integer> {    ONE(1, "一岁"),    TWO(2, "二岁"),    THREE(3, "三岁");    private int value;    @JsonValue //标注该字段要开启自定义序列化返回值    private String desc;    AgeEnum(int value, String desc) {        this.value = value;        this.desc = desc;    }    @Override    public Integer getValue() {        return this.value;    }//    @Override//    public String toString() {//        return this.desc;//    }}

说明:上面两种方式定义的枚举都是可以的,使用注解@EnumValue在使用起来会更简单一些。

3.2 在实体类中使用枚举

在需要的实体类中使用上面定义的枚举,这里重新创建一个实体类:

package com.kfit.user.model;import com.kfit.user.enums.AgeEnum;import com.kfit.user.enums.GradeEnum;import lombok.Data;/** * author:悟纤「公众号SpringBoot」 * date:2023/9/15 */@Datapublic class Student {    private Long id;    private String name;    /**     * 年龄,IEnum接口的枚举处理     * 数据库字段:age INT(3)     */    private AgeEnum age;    /**     * 年级,原生枚举(带{@link com.baomidou.mybatisplus.annotation.EnumValue}):     * 数据库字段:grade INT(2)     */    private GradeEnum grade;}

3.3 定义Mapper

由于实体类是新的,定义个Mapper进行数据库的操作,如果是在原实体添加的忽略这一个步骤:

package com.kfit.user.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.kfit.user.model.Student;/** * author:悟纤「公众号SpringBoot」 * date:2023/9/15 */public interface StudentMapper extends BaseMapper<Student> {}

3.4 在表中添加对应的列

在表中添加对应的列,这里实体类是新的,需要创建一个表:

CREATE TABLE student (     `id` bigint(0) NOT NULL AUTO_INCREMENT,     `name` varchar(255) NULL,     `age` int(3) NULL,     `grade` int(2) NULL,     PRIMARY KEY (`id`));

3.5 后端测试

接下来进行简单的后端测试。

3.5.1 保存测试

先来看下保存数据的测试:

@Autowiredprivate StudentMapper studentMapper;@Testpublic void testInsert(){    Student student = new Student();    student.setName("张三");    student.setAge(AgeEnum.ONE);    student.setGrade(GradeEnum.HIGH);    studentMapper.insert(student);}

执行结果:

3.5.2 修改测试

看下修改:

@Testpublic void testUpdate(){    Student student = new Student();    student.setId(1L);    student.setName("李四");    student.setAge(AgeEnum.TWO);    student.setGrade(GradeEnum.SECONDORY);    studentMapper.updateById(student);}

运行结果:

3.5.3 查询测试

看下返回的数据情况:

@Testpublic void testSelctById(){    Student student = studentMapper.selectById(1);    System.out.println(student);}

运行结果:

这里显示的希望是中文的描述的话,那么需要重写AgeEnum和GradeEnum的toString()方法:

@Overridepublic String toString() {    return this.desc;}

这时候在运行一下:

3.6 前端测试

最后在进行一下前端测试,就是从前端请求到控制层,然后进行操作。

3.6.1 定义一个controller

首先定义controller:

package com.kfit.user.controller;import com.kfit.user.mapper.StudentMapper;import com.kfit.user.model.Student;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * author:悟纤「公众号SpringBoot」 * date:2023/9/15 */@RestController@RequestMapping("/student")public class StudentController {    @Autowired    private StudentMapper studentMapper;}

3.6.2 查询测试

进行查询测试:

@RequestMapping("/select")public Student selectStudent(){    return studentMapper.selectById(1);}

请求地址:

http://127.0.0.1:8080/student/select

请求结果:

结果显示很正常,如果显示的不是中文的话,那么看看有没有在属性上添加了@JsonValue的注解,如果使用的是其它的JSON框架的话,那么对应的是什么注解。

3.6.3 保存测试

编写保存测试代码:

@RequestMapping("/save")public int save(@RequestBody Student student){    return studentMapper.insert(student);}

请求地址:

http://127.0.0.1:8080/student/save

请求体:

{    "name": "wuqian",    "age": "二岁",    "grade": "高中"}

请求结果:

除了 "age": "二岁","age": 1 也能达到相同的效果,需要注意的是:"age": 1 对枚举类的要求苛刻,需要保证枚举数字从0开始并按顺序排列,因为它是按顺序取枚举的。

也就是说:

设置age=0,那么对应的是ONE(1, "一岁");

设置age=1,那么对应的是TWO(2, "二岁");

如果要使用这种方式,最好是code从0开始,并且是顺序排列的,不然可能会出现莫名其妙的错误。

3.6.4 保存测试2

​上面保存是使用的JSON的方式,如果使用get请求地址这样的请求呢?

@RequestMapping("/save1")public int save1(Student student){    return studentMapper.insert(student);}

请求地址:

http://127.0.0.1:8080/student/save1?name=wuqian&age=二岁

请求报错:

Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors<EOL>Field error in object 'student' on field 'age': rejected value [二岁]; codes [typeMismatch.student.age,typeMismatch.age,typeMismatch.com.kfit.user.enums.AgeEnum,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.age,age]; arguments []; default message [age]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'com.kfit.user.enums.AgeEnum' for property 'age'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [com.kfit.user.enums.AgeEnum] for value [二岁]; nested exception is java.lang.IllegalArgumentException: No enum constant com.kfit.user.enums.AgeEnum.二岁]]

所以这种方式不能够这样子请求,可以这样子请求:

http://127.0.0.1:8080/student/save1?name=wuqian&age=ONE

请求结果:

那能不能传递value值呢 ?这个就需要重写StringToEnumConverterFactory的,可以自行去了解一下。

小结

本节介绍了MP的通用枚举功能,对于本文的知识重点总结一下:

(1)通用枚举定义的两种方式:其一使用注解@EnumValue;其二实现接口IEnum。

(2)后端测试想要返回对应的描述,可以重写toString()方法。

(3)前端测试想要返回对应的描述,可以添加注解@JsonValue。

(4)如果请求方式是json的方式,那么可以直接进行转换。

(5)如果请求方式是x-www-form-urlencoded,那么要使用name的方式,否则要重写类StringToEnumConverterFactory。

1000道互联网Java工程师面试题

包括了:MyBatis、ZK、Dubbo、EL、Redis、MySQL、并发编程、Java面试、Spring、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题(共 485 页,32W字)

领取方式:关注公众号「SpringBoot」,回复[面试资料]

👍 点赞、转发、评论,伸出你的双手666…


🐜i 你就是你,不一样的小蚂蚁!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/174465.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA数据类型和变量

一、字面常量 常量即程序运行期间&#xff0c;固定不变,不可修改的量称为常量。 public class Demo{public static void main(String[] args){System.Out.println("hello world!");System.Out.println(100);System.Out.println(3.14);System.Out.println(A);System…

Linux--进程替换

1.什么是进程替换 在fork函数之后&#xff0c;父子进程各自执行代码的一部分&#xff0c;但是如果子进程想要执行一份全新的程序呢&#xff1f; 通过进程替换来完成&#xff0c;进程替换就是父子进程代码发生写时拷贝&#xff0c;子进程执行自己的功能。 程序替换就是通过特定的…

maven环境变量,安装源,本地仓库配置

1. maven环境变量 我这里用的是idea自带的maven 数值为&#xff1a; D:\software\computer_software\java\IDEAJ\IDEAJ2021.2.1\IntelliJ IDEA 2021.2.1\plugins\maven\lib\maven3\bin 2. 安装源更换为阿里云&#xff08;我不知道清华源是什么网址&#xff0c;网上也没查到&am…

目标检测算法发展史

前言 比起图像识别&#xff0c;现在图片生成技术要更加具有吸引力&#xff0c;但是要步入AIGC技术领域&#xff0c;首先不推荐一上来就接触那些已经成熟闭源的包装好了再提供给你的接口网站&#xff0c;会使用别人的模型生成一些图片就能叫自己会AIGC了吗&#xff1f;那样真正…

Linux学习第25天:Linux 阻塞和非阻塞 IO 实验(二): 挂起

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 为方便和上一节的衔接&#xff0c;在正式开始学习前&#xff0c;先把本节的思维导图引入&#xff1a; 二、阻塞IO实验 1.硬件原理图分析 2.实验程序 #define I…

【排序算法】 归并排序详解!分治思想!

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; 算法—排序篇 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言&#x1f324;️归并排序的思想☁️基本思想☁️归并的思想实现☁️分治法 &#x1f3…

国产芯片vs“国际水平”,有距离也有超越!

当前&#xff0c;国产芯片正在迎来全新的发展阶段。国产终端芯片性能怎么样&#xff0c;与国际主流产品相比&#xff0c;表现如何&#xff1f;今天笔者就针对目前热度较高的四款国产CPU进行参数分析与性能跑分横向对比。 此次国产芯片评测型号分别是海光C86-3250、龙芯3A5000H…

Python 读取 Word 详解(python-docx)

文章目录 1 概述1.1 第三方库&#xff1a;python-docx 2 新建文档2.1 空白文档2.2 标题2.3 段落2.4 文本2.5 字体2.6 图片2.7 表格 3 扩展3.1 修改文档3.2 读取文档 1 概述 1.1 第三方库&#xff1a;python-docx > pip install python-docx2 新建文档 2.1 空白文档 impo…

idea中Run/Debug Python项目报错 Argument for @NotNull parameter ‘module‘ of ...

idea中Run/Debug Python项目报错 Argument for NotNull parameter module of ... idea中运行Python项目main.py时报错&#xff1a; Error running main: Argument for NotNull parameter module of com/intellij/openapi/roots/ModuleRootManager.getInstance must not be nu…

【jenkins】centos7在线安装jenkins

一、系统要求 最低推荐配置 256MB可用内存 1GB可用磁盘空间(作为一个Docker容器运行jenkins的话推荐10GB) 软件配置 Java 8—​无论是Java运行时环境&#xff08;JRE&#xff09;还是Java开发工具包&#xff08;JDK&#xff09;都可以 二、安装jenkins 准备一台安装有ce…

洞察运营机会的数据分析利器

这套分析方法包括5个分析工具&#xff1a; 用“描述性统计”来快速了解数据的整体特点。用“变化分析”来寻找数据的问题和突破口。用“指标体系”来深度洞察变化背后的原因。用“相关性分析”来精确判断原因的影响程度。用“趋势预测”来科学预测未来数据的走势&#xff0c;

系列四十、请谈一下Spring中事务的传播行为

一、概述 事务的传播行为指的是当一个事务方法被另一个事务方法调用时&#xff0c;这个事务方法应该如何进行。事务的传播行为至少发生在两个事务方法的嵌套调用中才会出现。 二、传播行为分类

Mysql进阶-索引篇(下)

SQL性能分析 SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供服务器状态信息。通过如下指令&#xff0c;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次&#xff0c;通过sql语句的访问频次&#xff0c;我们可…

使用Swift模拟用户登录当网获取数据并保存到MySQL中

前言 当当网作为中国最大的综合性网上商城之一&#xff0c;通过爬取当当网数据&#xff0c;我们可以获取商品信息、用户评价、销售数据等宝贵的信息资源。这些数据可以帮助企业了解市场趋势、分析竞争对手、优化产品定价等&#xff0c;从而做出更明智的决策。 为什么使用Swif…

3D网页游戏外包开发引擎

3D网页开发引擎是用于创建具有三维图形、虚拟现实和交互性的网页应用程序的工具。以下是一些常用的3D网页开发引擎以及它们的主要特点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.Three.js&…

Mysql设置了更新时间自动更新,指定更新部分sql时不进行时间更新

现象&#xff1a; 因为字段设置了自动更新&#xff0c;所以sql语句一进行修改此字段就会自动更新时间&#xff0c;但是呢我们的有部分定时任务是半夜执行&#xff0c;并且不能让这个任务修改到数据的更新时间 解决&#xff1a; <update id"updateCreative">ALT…

mac安装nodejs,跑vue程序

1. 下载node.js for mac&#xff0c;地址&#xff1a;Node.js。一路安装就可以了&#xff0c;无需修改。 2. mac终端&#xff0c;查看node和npm的版本。 3. 配置环境变量&#xff0c; vim .bash_profile增加PATH$PATH:/usr/local/bin/ 4. 但是毕竟npm安装一些东西还是太慢了所…

【网安AIGC专题10.19】论文6:Java漏洞自动修复+数据集 VJBench+大语言模型、APR技术+代码转换方法+LLM和DL-APR模型的挑战与机会

How Effective Are Neural Networks for Fixing Security Vulnerabilities 写在最前面摘要贡献发现 介绍背景&#xff1a;漏洞修复需求和Java漏洞修复方向动机方法贡献 数据集先前的数据集和Java漏洞Benchmark数据集扩展要求数据处理工作最终数据集 VJBenchVJBench 与 Vul4J 的…

Git基础命令实践

文章目录 简介git的安装配置git的安装git的配置 git使用的基本流程创建版本库时光机穿梭版本回退工作区和暂存区管理修改撤销修改删除文件 远程仓库添加远程库从远程库克隆 总结 简介 本文主要记录了我在学习git操作的过程&#xff0c;以及如何使用GitHub。建议先参考廖雪峰的…