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. 用反射的方法获取枚举值(数据字典)

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

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

相关文章

Mac不想用iTerm2了怎么办

这东西真是让人又爱又恨&#xff0c;爱的是它的UI还真不错&#xff0c;恨的是它把我的环境给破坏啦&#xff01;让我每次启动终端之后都要重新source激活我的python环境&#xff0c;而且虚拟环境前面没有括号啦&#xff01;这怎么能忍&#xff01;在UI和实用性面前我断然选择实…

C语言学习:6、C语言程序的循环结构

生活中&#xff0c;有很多循环的东西&#xff0c;比如钟表就是在1到12循环&#xff0c;太阳东升西落也是循环&#xff0c;春夏秋冬也是循环&#xff0c;人生可能也是一个循环。 while C语言中的循环可以这么描述&#xff1a;当某个条件成立&#xff0c;就一直做某件事或某些事…

学习笔记——Java入门第一季

1.1 Java的介绍与前景 Java语言最早期的制作者&#xff1a;James Gosling&#xff08;詹姆斯高斯林&#xff09; 1995年5月23日&#xff0c;Sun Microsystems公司宣布Java语言诞生。 1.2 Java的特性与版本 跨平台 开源&#xff08;开放源代码&#xff09; Java代码&#xff…

SSM整合~

构建并配置项目&#xff1a; 第一步&#xff1a;创建maven项目 第二步&#xff1a;配置pom.xml文件 设置打包方式&#xff1a; 为了方便部署&#xff0c;我们通常情况下&#xff0c;将项目打包为WAR&#xff0c;因为WAR文件是一种可执行的压缩文件&#xff0c;它可以将项目…

MATLAB中fillmissing函数用法

目录 语法 说明 示例 包含 NaN 值的向量 由 NaN 值组成的矩阵 插入缺失数据 使用移动中位数方法 使用自定义填充方法 包含缺失端点的矩阵 包含多个数据类型的表 fillmissing函数的功能是填充缺失的条目。 语法 F fillmissing(A,constant,v) F fillmissing(A,meth…

Linux——线程详解(一)

索引 初识线程1.inux下的线程2.再谈进程3.理解页表4. 再次理解虚拟到物理的转化 线程的控制1.线程的创建2.线程异常3.验证pthread_join 的第二个参数4.线程的退出方式5. 线程的公有和私有6.pthread_t 与线程独立栈7.线程的局部性存储8.线程分离 初识线程 1.inux下的线程 之前了…

【数据结构】单链表详解

当我们学完顺序表的时候&#xff0c;我们发现了好多问题如下&#xff1a; 中间/头部的插入删除&#xff0c;时间复杂度为O(N)增容需要申请新空间&#xff0c;拷贝数据&#xff0c;释放旧空间。会有不小的消耗。增容一般是呈2倍的增长&#xff0c;势必会有一定的空间浪费。例如当…

光栅和矢量图像处理:Graphics Mill 11.4.1 Crack

Graphics Mill 是适用于 .NET 和 ASP.NET 开发人员的最强大的成像工具集。它允许用户轻松向 .NET 应用程序添加复杂的光栅和矢量图像处理功能。 光栅图形 加载和保存 JPEG、PNG 和另外 8 种图像格式 调整大小、裁剪、自动修复、色度键和 30 多种其他图像操作 可处理任何尺寸&am…

AJAX学习笔记1发送Get请求

传统请求有哪些方式,及缺点 传统请求有哪些? 1.直接在浏览器地址栏上输入URL. 2.点击超连接. <a href"/上下文/请求地址">超链接请求</a> ---->相对路径 <a href"http://www.baidu.com">超链接请求</a> ---->绝对路…

【前端】React项目初体验

React介绍 React 是一个非常流行的 JavaScript 前端框架&#xff0c;它为开发人员提供了一种快速构建高质量用户界面的方式。以下是使用 React 构建项目的初体验&#xff1a; 安装 React 和相关依赖项 使用 React 开发项目需要先安装一些必需的依赖项&#xff0c;包括 Node.…

Echarts 中国地图

直接展示效果图&#xff1a; 我们需要引入两个文件&#xff1a; echarts.js 官网地址下载&#xff1a;快速上手 - Handbook - Apache ECharts chain.js 这个官网已经找不到了&#xff0c;需要自行搜寻下载 也可以私信我(网上下载的China.js会导致省名称定为不准确&#xff0…

leetcode 1002. 查找共用字符

2023.9.6 个人感觉这题难度不止简单&#xff0c;考察到的东西还是挺多的。 首先理解题意&#xff0c;可以将题意转化为&#xff1a;求字符串数组中 各字符串共同出现的字符的最小值。 分为三步做&#xff1a; 构造一个哈希表hash&#xff0c;初始化第一个字符串的字母出现频率…

如何挑选低值易耗品管理系统?优化企业管理效率与成本控制

在现代企业管理中&#xff0c;低值易耗品的管理是一个容易被忽视但却十分重要的环节。低值易耗品包括办公用品、耗材、工具等&#xff0c;它们虽然单价不高&#xff0c;但数量庞大且频繁使用&#xff0c;对企业的日常运营和成本控制有着重要影响。为了提高管理效率、降低成本&a…

【Git】删除本地分支;报错error: Cannot delete branch ‘wangyunuo-test‘ checked out at ‘XXX‘

目录 0.环境 1.问题描述 2.解决步骤 1&#xff09;使用命令切换到其他分支 2&#xff09;查看当前本地所有分支 3&#xff09;删除“wangyunuo-test”分支 0.环境 windows 11 64位 Git VScode跑代码 1.问题描述 在做项目过程中&#xff0c;想删除一个本地分支“wangyun…

JS返回NodeList和HTMLCollection详解

HTML DOM 集合 (Collection) 概述 HTML DOM 集合 (Collection) 是一组 HTML 元素&#xff0c;这些元素可以通过 JavaScript 代码进行访问和操作。HTML DOM 集合通常由一个或多个 HTML 元素组成&#xff0c;并提供了访问和操作这些元素的方法。HTML DOM 集合在 JavaScript 中非常…

解决DCNv2不能使用高版本pytorch编译的问题

可变形卷积网络GitHub - CharlesShang/DCNv2: Deformable Convolutional Networks v2 with Pytorch代码已经出来好几年了&#xff0c;虽然声称"Now the master branch is for pytorch 1.x"&#xff0c;实际上由于pytorch自1.11版开始发生了很大变化&#xff0c;原来基…

JAVA毕业设计096—基于Java+Springboot+Vue的在线教育系统(源码+数据库+18000字论文)

基于JavaSpringbootVue的在线教育系统(源码数据库18000字论文)096 一、系统介绍 本系统前后端分离 本系统分为管理员、用户两种角色(管理员角色权限可自行分配) 用户功能&#xff1a; 注册、登录、课程预告、在线课程观看、学习资料下载、学习文章预览、个人信息管理、消息…

elementUI——el-table自带排序使用问题

问题 排序表格默认第一列按降序排&#xff08;状态1&#xff09;&#xff0c;当点击其他列后&#xff08;状态2&#xff09;&#xff0c;改变日期&#xff0c;触发表格数据更新&#xff0c;发现列的排序还点亮在之前的操作上&#xff0c;没有按照默认来&#xff08;回到状态1&a…

Rokid Jungle--Max pro

介绍和功能开发 YodaOS-Master操作系统&#xff1a;以交换计算为核心&#xff0c;实现单目SLAM空间交互&#xff0c;具有高精度、实时性和稳定性。发布UXR2.0SDK&#xff0c;为构建空间内容提供丰富的开发套件 多模态交互 算法原子化 多种开发工具协同 多生态支持 骁龙XR2…

【C++精华铺】10.STL string模拟实现

1. 序言 STL&#xff08;标准模板库&#xff09;是一个C标准库&#xff0c;其中包括一些通用的算法、容器和函数对象。STL的容器是C STL库的重要组成部分&#xff0c;它们提供了一种方便的方式来管理同类型的对象。其中&#xff0c;STLstring是一种常用的字符串类型。 STLstrin…