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.mzph.cn/news/124348.shtml

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

相关文章

3D LUT 滤镜 shader 源码分析

最近在做滤镜相关的渲染学习&#xff0c;目前大部分 LUT 滤镜代码实现都是参考由 GPUImage 提供的 LookupFilter 的逻辑&#xff0c;整个代码实现不多。参考网上的博文也有各种解释&#xff0c;参考了大量博文之后终于理解了&#xff0c;所以自己重新整理了一份&#xff0c;方便…

JMeter的使用——傻瓜式学习【中】

目录 前言 1、JMeter参数化 1.1、什么是参数化 1.2、用户定义的变量 1.2.1、什么时候使用用户定义的变量 1.2.2、使用“用户定义的变量”进行参数化的步骤&#xff1a; 1.2.3、案例 1.3、用户参数 1.3.1、什么时候使用用户参数&#xff1f; 1.3.2、使用“用户参数”进…

VScode 调试 linux内核

VScode 调试 linux内核 这里调试的 linux 内核是通过 LinuxSD卡(rootfs)运行的内核 gdb 命令行调试 编辑 /home/tyustli/.gdbinit 文件&#xff0c;参考 【GDB】 .gdbinit 文件 set auto-load safe-path /home/tyustli/code/open_source/kernel/linux-6.5.7/.gdbinit在 lin…

PFAF-Net

I 1 _1 1​和I 2 _2 2​是多模态图像&#xff0c;I F _F F​是融合图像。FT 1 _1 1​是基于空间注意力的融合&#xff0c;FT 2 _2 2​是基于通道注意力的融合 作者未提供代码

docker的安装部署nginx和mysql

小白自己整理&#xff0c;如有错误请指示&#xff01; 自我理解&#xff1a;docker就是把应用程序所用的依赖程序&#xff0c;函数库等相关文件打包成镜像文件&#xff0c;类似系统光盘&#xff0c;然后可以在任意电脑上安装使用&#xff08;方便运维人员部署程序&#xff09;…

Ansible的安装和部署

目录 1.Ansible的安装 2.构建Ansible清单 直接书写受管主机名或ip 设定受管主机的组[组名称] 主机规格的范围化操作 指定其他清单文件 ansible命令指定清单的正则表达式 3.Ansible配置文件参数详解 配置文件的分类与优先级 常用配置参数 4.构建用户级Ansible操作环…

Spring面试题:(一)IoC,DI,AOP和BeanFactory,ApplicationContext

IoC&#xff0c;DI&#xff0c;AOP思想 IOC就是控制反转&#xff0c;是指创建对象的控制权的转移。以前创建对象的主动权和时机是由自己把控的&#xff0c;而现在这种权力转移到Spring容器中&#xff0c;并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系。对象与对…

c++设计模式三:工厂模式

本文通过一个例子简单介绍简单工厂模式、工厂模式和抽象工厂模式。 1.简单工厂&#xff08;静态&#xff09; 假如我想换个手机&#xff0c;换什么手机呢&#xff1f;可以考虑苹果或者华为手机&#xff0c;那我们用简单工厂模式来实现这个功能&#xff1a; 我们关注的产品是手…

ubuntu部署个人网盘nextCloud使用docker-compose方式

概述 当下各大网盘的容量都是有限制的&#xff0c;而且xx云不开会员网速就拉跨。 所以就想搭建一个自己的盘&#xff0c;并且可以控制用户的权限分组&#xff1b; nextCloud就很合适 我这边都是自己用偶尔给其他人使用下&#xff0c;所以直接docker部署了。 ubuntu版本&…

【2023.10.30练习】C语言-循环右移字符

计算机能力挑战初赛2020.19题 题目描述&#xff1a; 现要对一个由字符a-z和A-Z组成的字符串进行解密&#xff0c;已知加密规则是&#xff1a; 字符串中所有字符分别在大写或小写的字母表中被循环左移5位(fGh-->aBc)&#xff0c; 输入&#xff1a;一个加密过的字符串&#…

3.6每日一题(线性方程求通解)

1、判断类型选择方法&#xff1a;发现以y为未知函数&#xff0c;以x为自变量&#xff0c;不符合我们学过的类型 2、此时有两种方法&#xff1a; &#xff08;1&#xff09;x 与 y 对调&#xff0c;此时 x 为未知函数&#xff0c;y 为自变量 &#xff08;2&#xff09;变量代换…

10.27~10.29数电第三次实验分析与问题

实验要求 分析 寄存器 D触发器有两个输出口&#xff0c;一个输入口&#xff0c;一个时钟信号&#xff0c;一个复位信号 同步异步就是说复位信号在不在always里 给它加一个load就成了一位寄存器&#xff0c; 寄存器堆 8个8位的寄存器堆&#xff0c;每个寄存器都有两读一写…

【Leetcode】【简单】13. 罗马数字转整数

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/roman-to-integer/description/ …

在win10下,使用torchviz对深度学习网络模型进行可视化

目录 1. 安装 graphviz 和 torchviz 2.安装 graphviz.exe 3.实例测试 4.如果你的电脑还是无法画图&#xff0c;并且出现了下面的报错&#xff1a; 5.参考文章&#xff1a; 1. 安装 graphviz 和 torchviz 首先打开 Anaconda prompt 进入自己的 pytorch 环境(图中 pt 是我自…

servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header

目录 1、cookie和Session以及Header知识点 2、设置/获取 Cookie 3、设置/获取Session 4、设置/获取Header Cookie —— 客户端机制 Session —— 服务端机制 本篇博客主在用servlet和SpringBoot两种方式分别获取Session和Cookie&#xff0c;用来比较记忆与分析 1、cookie和…

MSQL系列(十二) Mysql实战-为什么索引要建立在被驱动表上

Mysql实战-left/right/inner join 使用详解 前面我们讲解了BTree的索引结构&#xff0c;也详细讲解下 left Join的底层驱动表 选择原理&#xff0c;那么今天我们来实战一下 left join&#xff0c;right join&#xff0c;inner join 等sql命令&#xff0c;看看到底如何用以及如…

Leetcode周赛369补题(3 / 3)

目录 1、找出数组的K-or值 - 位运算 模拟 2、数组的最小相等和 - 分情况讨论 3、使数组变美的最小增量运算数 - 动态规划dp 1、找出数组的K-or值 - 位运算 模拟 100111. 找出数组中的 K-or 值 思路&#xff1a; 根据范围&#xff0c;我们可以枚举0~30位&#xff0c;然后在…

数据库软考知识

分布式数据库透明性 封锁 加上共享锁之后只能加共享锁&#xff0c;加上排他锁之后&#xff0c;啥锁都不能加。 分布式数据库特性 伪传递定理 SQL函数定义&#xff0c;有点冷 来了奥&#xff0c;更冷 存储过程 很重要&#xff0c;下午第二大题也是数据库

Java精品项目源码爱心捐赠平台网站(编号V65)

Java精品项目源码扶农助农平台建设系统(编号V64) 大家好&#xff0c;小辰今天给大家介绍一个爱心捐赠平台网站(编号V65)&#xff0c;演示视频公众号&#xff08;小辰哥的Java&#xff09;对号查询观看即可 文章目录 Java精品项目源码扶农助农平台建设系统(编号V64)难度指数&a…

开源B2B网站电子商务平台源码下载搭建 实现高效交易的桥梁

随着互联网的普及和电子商务的快速发展&#xff0c;B2B&#xff08;Business-to-Business&#xff09;网站电子商务平台在商业领域中发挥着越来越重要的作用。通过开源B2B网站电子商务平台源码搭建&#xff0c;企业可以构建自己的电子商务平台&#xff0c;实现高效交易的桥梁。…