当前位置: 首页 > news >正文

Java:Springboot和React中枚举值(数据字典)的使用

目录

    • 1、开发中的需求
    • 2、实现效果
    • 3、后端代码
    • 4、前端代码
    • 5、接口数据
    • 6、完整代码
    • 7、参考文章

1、开发中的需求

开发和使用过程中,通常会涉及四个角色:数据库管理员、后端开发人员、前端开发人员、浏览者

  • 数据库使用int类型的数值进行存储(eg: 0、1、2)
  • Java代码使用enum枚举类型的对象进行逻辑判断(eg: SexEnum.UNKOWN SexEnum.MAN、SexEnum.WOMAN)
  • 接口返回枚举值的字符串形式用于必要的逻辑判断(eg: UNKOWN、MAN、WOMAN)
  • 显示给用户查看(eg: 未知、男性、女性)
使用方数值类型用途示例
数据库int数值存储0、1、2
后端代码Enum枚举类逻辑判断SexEnum.UNKOWN SexEnum.MAN、SexEnum.WOMAN
前端代码string常量字符串逻辑判断UNKOWN、MAN、WOMAN
用户视图string字符串查看未知、男性、女性

假设:

1、如果后端返回数字,数字本身没有很直观的意思,不便于前端人员检查问题,如果书写错误,同样会导致不容易发现的问题。

2、如果后端返回用户友好的字符串,前端如果需要做逻辑判断就很不好,毕竟不知道产品经理什么时候会把显示的内容修改掉,比如:男性 改为 男

3、如果后端返回枚举类型的常量字符串,那每次需要显示的时候,都必须做一个映射转换,前端人员也很苦恼

综上:

后端同时返回 枚举字符串 和 用户友好的字符串 比较好,既方便前端人员做逻辑判断,也方便给用户展示;

一般情况下,枚举类型统一在后端维护,如果需要修改,也只需要修改一个地方就可以

如果,前端也需要使用枚举值进行逻辑判断,那么前端也需要和后端约定好的映射关系自己定义好枚举,可以直接使用常量字符串作为枚举,前端显示的值可以和后端约定好,什么数值,显示什么字符串

同时,需要给前端返回一个枚举映射关系表,用于下拉选择等业务

2、实现效果

1、列表页

  1. 顶部筛选类型由接口返回,接口增加类型后,前端代码不用修改,直接生效
  2. 列表性别 列,直接显示后端返回sexLabel的字段
  3. 列表颜色 列,由于前端需要根据不同的值,做一些逻辑判断,所以前端代码也需要做好枚举,做逻辑判断,此时需要注意默认值 ,预防后端增加类型之后,前端代码增加容错

在这里插入图片描述
2、添加页

性别颜色 都使用后端返回的配置数据即可,后端增加类型数据之后,前端无需修改代码
在这里插入图片描述

3、后端代码

配合MyBatis-Plus使用,可以很容易进行数据库和代码之间的转换

定义3个值,由后端代码统一维护

code  # 用于数据库存储
value # 用于后端和前端的逻辑判断
label # 用户展示给用户

如果有其他属性,也可以增加

先定义一个通用的枚举接口

package com.example.demo.enums;/*** 字典枚举接口*/
public interface IDictEnum {Integer getCode();String getLabel();String name();// @JsonValue // 标记响应json值default String getValue() {return this.name();}
}

定义枚举类

package com.example.demo.enums;import com.baomidou.mybatisplus.annotation.EnumValue;/*** 性别枚举*/
public enum SexEnum implements IDictEnum {/*** 男性*/MAN(1, "男性"),/*** 女性*/WOMEN(2, "女性");/*** 存储值*/@EnumValue // 配置 mybatis-plus 使用 标记数据库存的值是 codeprivate final Integer code;/*** 显示值*/private final String label;SexEnum(Integer code, String label) {this.code = code;this.label = label;}@Overridepublic Integer getCode() {return this.code;}@Overridepublic String getLabel() {return this.label;}
}

自动扫描枚举类

package com.example.demo.config;import com.example.demo.vo.EnumVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** 枚举配置类*/
@Slf4j
@Component
public class DictEnumConfig {// 通同匹配private static final String RESOURCE_PATTERN = "/**/*Enum.class";// 扫描的包名private static final String BASE_PACKAGES = "com.example.demo.enums";private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();@Bean(name = "enumConfig")public Map<String, List<EnumVO>> enumConfig() {Map<String, List<EnumVO>> enumMap = new HashMap<>();try {// 根据classname生成class对应的资源路径,需要扫描的包路径//ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +String pattern = ClassUtils.convertClassNameToResourcePath(BASE_PACKAGES) + RESOURCE_PATTERN;// 获取classname的IO流资源Resource[] resources = resourcePatternResolver.getResources(pattern);// MetadataReaderFactory接口 ,MetadataReader的工厂接口。允许缓存每个MetadataReader的元数据集MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);for (Resource resource : resources) {if (resource.isReadable()) {// 通过class资源(resource)生成MetadataReaderMetadataReader reader = readerFactory.getMetadataReader(resource);// 获取class名String className = reader.getClassMetadata().getClassName();Class<?> clz = Class.forName(className);if (!clz.isEnum()) {continue;}// 将枚举类名首字母转小写,去掉末尾的EnumenumMap.put(clz.getSimpleName(), this.enumToList(clz));}}} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return enumMap;}public List<EnumVO> enumToList(Class<?> dictEnum) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {List<EnumVO> list = new ArrayList<>();Method valuesMethod = dictEnum.getMethod("values");Object[] values = (Object[]) valuesMethod.invoke(null);for (Object obj : values) {EnumVO enumVO = new EnumVO();BeanUtils.copyProperties(obj, enumVO);list.add(enumVO);}return list;}
}

4、前端代码

前端定义一个全局的变量,来存储数据字典,可以在应用初始化前就请求接口获取数据,确保后续组件中正常使用

import http from "../api/index.js";/*** 全局静态数据*/
export const globalData = {SexEnum: [],ColorEnum: [],
};// 初始化
export async function initGlobalData() {const res = await http.get("/getEnumConfig");for (const key in globalData) {globalData[key] = res[key];}
}// === getter ===
export function getSexEnumFilterOptions() {console.log(globalData);return [{ value: "", label: "全部" }, ...globalData.SexEnum];
}export function getSexEnumOptions() {return globalData.SexEnum;
}export function getColorEnumOptions() {return globalData.ColorEnum;
}

前端需要进行逻辑判断,可自行枚举

/*** 颜色枚举,前端代码需要逻辑判断*/
export const ColorEnum = {// 红色RED: 'RED',// 绿色GREEN: 'GREEN',// 蓝色BLUE: 'BLUE',
};export const ColorEnumOptions = [{// 红色value: ColorEnum.RED,color: 'error',},{// 绿色value: ColorEnum.GREEN,color: 'success',},{// 蓝色value: ColorEnum.BLUE,color: 'processing',},
];export function getColorEnumColor(value) {return (ColorEnumOptions.find((item) => item.value === value)?.color || 'default');
}

5、接口数据

直接返回value和label字段,便于直接对接element和antd UI组件库,不需要再进行数据转换

获取枚举配置

GET http://localhost:8080/getEnumConfig{"ColorEnum": [{"value": "RED","label": "红色"},{"value": "GREEN","label": "绿色"},{"value": "BLUE","label": "蓝色"}],"SexEnum": [{"value": "MAN","label": "男性"},{"value": "WOMEN","label": "女性"}]
}

前端提交数据

POST http://localhost:8080/addUser
Content-Type: application/json{"name": "Steve","sex": "WOMEN"
}

前端获取数据

GET http://localhost:8080/getUserList[{"id": 21,"name": "Steve","sex": "WOMEN","color": null,"sexLabel": "女性","colorLabel": ""}
]

sexLabel 为方便前端显示数据而增加的字段

6、完整代码

后端代码:https://github.com/mouday/spring-boot-demo/SpringBoot-Enum
前端代码:https://gitee.com/mouday/react-enum

7、参考文章

  1. 看看人家在接口中使用枚举类型的方式,那叫一个优雅!
  2. Spring IoC资源管理之ResourceLoader
  3. 通过Spring包扫描的形式将枚举以字典的形式返回
  4. MyBatis-Plus:通用枚举
  5. 用反射的方法获取枚举值(数据字典)

相关文章:

Java:Springboot和React中枚举值(数据字典)的使用

目录 1、开发中的需求2、实现效果3、后端代码4、前端代码5、接口数据6、完整代码7、参考文章 1、开发中的需求 开发和使用过程中&#xff0c;通常会涉及四个角色&#xff1a;数据库管理员、后端开发人员、前端开发人员、浏览者 数据库使用int类型的数值进行存储&#xff08;e…...

git撤回 不小心 commit 进去的文件

我时候 我们可能讲一下不想提交的文件 不小心commit了进去 我们可以通过 git reset HEAD~来撤回刚才的添加记录...

qt之movetothread理解

基础概念 qt的下线程qthread&#xff0c;每个线程都有自己的事件循环exec。对象的线程上下文&#xff0c;每个对象都有自己的线程上下文&#xff0c;怎么理解呢&#xff0c;就是该对象在哪个线程创建&#xff0c;其线程上下文就是谁。每个qobject对象在创建时都有包含线程成员…...

深入剖析:垃圾回收你真的了解吗?

小熊学Java&#xff1a;https://www.javaxiaobear.cn/ 本文我们重点剖析 JVM 的垃圾回收机制。关于 JVM 垃圾回收机制面试中主要涉及这三个考题&#xff1a; JVM 中有哪些垃圾回收算法&#xff1f;它们各自有什么优劣&#xff1f; CMS 垃圾回收器是怎么工作的&#xff1f;有哪…...

ue5 物理场的应用

cable mat wpo particle 流体粒子 choas 破损 刚体 布料 cloud abp blueprint riggedbody 体积雾 毛发 全局的 局部的 非均匀的 连续变化的 也可以多个叠加 从全局 到 范围 除了vector还有scalar的值也就是0--1的黑白灰的值 但是最终输出的值的类型还是取决于这个 一…...

移动零00

题目链接 移动零 题目描述 注意点 将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序必须在不复制数组的情况下原地对数组进行操作 解答思路 采用双指针的思路&#xff0c;左指针指向已移动零的数组的尾部&#xff0c;右指针指向为移动零的数组的头部&…...

go初识iris框架(四) -框架设置操作

前言 iris(1) iris(2) iris(3) 框架设置操作 当我们的一个路径是xxx/user/info,xxx/user/login,xxx/user/register的时候,我们发现前面都有一个user,我们如果用/{data:string}这样的话这样导致我们的路径是灵活的&#xff0c;所以我们得用其他方法 这里我们的路径是以anime为…...

python基础语法(二)

目录 注释注释的语法注释行文档字符串 注释的规范 输入输出和用户的交互通过控制台输出通过控制台的输入 注释 注释的语法 注释行 python的注释:使用#开通的行都是注释 # 这是一行注释C语言的注释:使用//的都是注释 // 这是一行注释文档字符串 使用三引号引起来的称为文档…...

从本地到Gitee:一步步学习文件上传及解决常见报错问题

&#x1f642;博主&#xff1a;小猫娃来啦 &#x1f642;文章核心&#xff1a;一步步学习文件上传及解决常见报错问题 文章目录 安装git进入gitee官网&#xff0c;登录账号新建仓库先打开git命令行上传本地资源到仓库第一步&#xff1a;git init第二步&#xff1a;git add .第三…...

idea2018修改大小写提示(敏感)信息

操作步骤如下&#xff1a; File > Settings > Editor > Code Completion > Code Completion&#xff08;默认是首字母&#xff0c;选为none将不区分大小写&#xff09;...

Quartz.Net调度框架简介

Quartz.Net是一个功能强大的开源任务调度框架&#xff0c;它可以在C#应用程序中实现灵活、可靠的任务调度和定时作业。它的主要作用是允许开发人员按照预定的时间表执行各种任务&#xff0c;例如定期生成报表、发送电子邮件、备份数据等。 在C#中使用Quartz.Net进行配置、开发…...

HarmonyOS/OpenHarmony(Stage模型)应用开发组合手势(一)连续识别

组合手势由多种单一手势组合而成&#xff0c;通过在GestureGroup中使用不同的GestureMode来声明该组合手势的类型&#xff0c;支持连续识别、并行识别和互斥识别三种类型。 .GestureGroup(mode:GestureMode, …gesture:GestureType[]) mode&#xff1a;必选参数&#xff0c;为G…...

Redis --- 位图

目录 背景 结构 存取方式 统计和查找 背景 开发过程中&#xff0c;会有布尔类型的存储&#xff0c;比如记录一个用户一年365天的签到情况&#xff0c;如果每天都要有一个布尔变量&#xff0c;多个用户&#xff0c;亦或者使用k-v形式&#xff0c;上亿用户的话这个存储量是惊…...

自然语言处理-词向量模型-Word2Vec

通常数据的维度越高&#xff0c;能提供的信息也就越多&#xff0c;从而计算结果的可靠性就更值得信赖 如何来描述语言的特征呢&#xff0c;通常都在词的层面上构建特征&#xff0c;Word2Vec就是要把词转换成向量 假设现在已经拿到一份训练好的词向量&#xff0c;其中每一个词都…...

List知识总结

ArrayList: 1 ArrayList扩容底层用到的是&#xff1b;System.arraycopy. 2 扩容的长度计算&#xff1b;int newCapacity oldCapacity (oldCapacity >> 1);&#xff0c;旧容量 旧容量右移1位&#xff0c;这相当于扩容为原 来容量的(int)3/2. 3 ArrayList<String…...

代码随想录day32

122.买卖股票的最佳时机 II ● 力扣题目链接 ● 给定一个数组&#xff0c;它的第 i 个元素是一支给定股票第 i 天的价格。 ● 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;。 ● 注意&#xff1a;你不能同…...

2.8 PE结构:资源表详细解析

在Windows PE中&#xff0c;资源是指可执行文件中存放的一些固定不变的数据集合&#xff0c;例如图标、对话框、字符串、位图、版本信息等。PE文件中每个资源都会被分配对应的唯一资源ID&#xff0c;以便在运行时能够方便地查找和调用它们。PE文件中的资源都被组织成一个树形结…...

Python数据类型的相互转换

简单数据类型之间的转换 1.字符串如果是数字的&#xff0c;转换为int类型 a "10" a int(a) print(a) 2.数字类型转换成bool类型 a 10 a bool(a) print(a) 只有0才是false&#xff0c;其他值是True 复杂数据类型之间的转换 list&#xff1a;列表 tuple&…...

阿里云云主机免费试用三个月

试用链接如下&#xff1a; 阿里云云产品免费试用 云主机 费用试用三个月&#xff0c;每月750小时 实例规格 1核(vCPU) 2 GiB S6 系列机型 适用搭建网站等场景 网络带宽 1M 公网固定网络带宽 云盘40 GiB 真香&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…...

OpenHarmony 使用 ArkUI Inspector 分析布局

● 摘要&#xff1a;视图的嵌套层次会影响应用的性能&#xff0c;开发者应该移除多余的嵌套层次&#xff0c;缩短组件刷新耗时。本文会介绍如何使用 ArkUI Inspector 工具分析布局&#xff0c;提示应用响应性能。 ● 关键字&#xff1a;列举本文相关的关键字&#xff1a;OpenH…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...