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

Spring boot中实现字典管理

数据库脚本

CREATE TABLE `data_dict` (`id` bigint NOT NULL COMMENT '主键',`dict_code` varchar(32) DEFAULT NULL COMMENT '字典编码',`dict_name` varchar(64) DEFAULT NULL COMMENT '字典名称',`dict_description` varchar(255) DEFAULT NULL COMMENT '字典描述',`dict_status` tinyint DEFAULT NULL COMMENT '字典状态;0:禁用;1:启用',`created_by` varchar(32) DEFAULT NULL COMMENT '创建人;姓名[域账号]',`created_time` datetime DEFAULT NULL COMMENT '创建时间',`updated_by` varchar(32) DEFAULT NULL COMMENT '更新人;姓名[域账号]',`updated_time` datetime DEFAULT NULL COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据字典';INSERT INTO data_dict (id, dict_code, dict_name, dict_description, dict_status, created_by, created_time, updated_by, updated_time) VALUES(1889143437849174016, 'test', 'test', 'test', 1, 'xx', '2025-02-11 10:44:29', 'xx', '2025-02-11 10:44:29');
INSERT INTO data_dict (id, dict_code, dict_name, dict_description, dict_status, created_by, created_time, updated_by, updated_time) VALUES(1889143437849174017, 'test2', 'test2', 'test2', 1, 'xx', '2025-02-11 10:44:29', 'xx', '2025-02-11 10:44:29');CREATE TABLE `data_dict_item` (`id` bigint NOT NULL COMMENT '主键',`dict_code` varchar(32) DEFAULT NULL COMMENT '字典编码',`item_code` varchar(32) DEFAULT NULL COMMENT '条目编码',`item_value` varchar(255) DEFAULT NULL COMMENT '条目值',`item_description` varchar(255) DEFAULT NULL COMMENT '条目描述',`item_status` tinyint DEFAULT NULL COMMENT '条目状态;0:禁用;1:启用',`seq` int DEFAULT NULL COMMENT '序号',`created_by` varchar(32) DEFAULT NULL COMMENT '创建人;姓名[域账号]',`created_time` datetime DEFAULT NULL COMMENT '创建时间',`updated_by` varchar(32) DEFAULT NULL COMMENT '更新人;姓名[域账号]',`updated_time` datetime DEFAULT NULL COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据字典条目';INSERT INTO data_dict_item (id, dict_code, item_code, item_value, item_description, item_status, seq, created_by, created_time, updated_by, updated_time) VALUES(1889143437849174016, 'test', 'xxx', 'xx', 'xxx', 1, 1, 'xx', '2025-02-11 10:44:29', 'xx', '2025-02-11 10:44:29');
INSERT INTO data_dict_item (id, dict_code, item_code, item_value, item_description, item_status, seq, created_by, created_time, updated_by, updated_time) VALUES(1889143437849174017, 'test2', '111', '222', 'xxx', 1, 1, 'xx', '2025-02-11 10:44:29', 'xx', '2025-02-11 10:44:29');
INSERT INTO data_dict_item (id, dict_code, item_code, item_value, item_description, item_status, seq, created_by, created_time, updated_by, updated_time) VALUES(1889143437849174018, 'test2', '33', '44', 'xxx', 1, 1, 'xx', '2025-02-11 10:44:29', 'xx', '2025-02-11 10:44:29');

代码

package com.demo.dto.sys;import lombok.Data;
import lombok.experimental.Accessors;import java.io.Serial;
import java.io.Serializable;/*** 字典缓存** @since 2025/02/11 上午 10:39*/
@Data
@Accessors(chain = true)
public class DataDictItemCache implements Serializable {@Serialprivate static final long serialVersionUID = -2394718872868472043L;/*** 字典编码*/private String dictCode;/*** 条目编码*/private String itemCode;/*** 条目值*/private String itemValue;/*** 条目状态;0:禁用;1:启用*/private Integer itemStatus;
}
package com.demo.annotation;import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.demo.config.DictSerializer;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 数据字典注解** @since 2025/02/08 下午 01:41*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DictSerializer.class)
public @interface Dict {/*** 字典编码*/String dictCode();
}// 使用方式如下// @Data
// public class Test {
//
//     @Dict(dictCode = "xxx")
//     private String itemCode;
//
//     private String other;
// }// {
//     "code": 200,
//     "message": "操作成功",
//     "result": {
//         "itemCode": {
//             "dictCode": "xxx",
//             "itemCode": "111",
//             "itemValue": "222",
//             "itemStatus": 1
//         },
//         "other": null
//     },
//     "timestamp": "1739245075643"
// }
package com.demo.config;import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
import com.demo.annotation.Dict;
import org.springframework.stereotype.Component;import java.io.Serial;/*** 字典注解序列化拦截器** @since 2025/02/08 下午 02:20*/
@Component
public class DictAnnotationIntrospector extends NopAnnotationIntrospector {@Serialprivate static final long serialVersionUID = 5139608634773791712L;@Overridepublic Object findSerializer(Annotated am) {Dict dict = am.getAnnotation(Dict.class);if (dict != null) {return DictSerializer.class;}return null;}
}
package com.demo.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 修改被@Dict注解标注的属性字典序列化方式** @since 2025/02/08 下午 02:22*/
@Configuration
public class DictSerializerConfig {@Autowiredprivate DictAnnotationIntrospector dictAnnotationIntrospector;@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {return builder -> builder.annotationIntrospector(dictAnnotationIntrospector);}
}
package com.demo.config;import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.demo.annotation.Dict;
import com.demo.service.sys.DataDictItemService;
import com.demo.dto.sys.DataDictItemCache;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;import java.io.IOException;
import java.io.Serial;
import java.util.List;/*** 数据字典自定序列化类** @since 2025/02/08 下午 02:18*/
public class DictSerializer extends StdSerializer<Object> implements ContextualSerializer {@Serialprivate static final long serialVersionUID = -3774620761859983477L;/*** 字典编码*/private final String dictCode;public DictSerializer() {super(Object.class);this.dictCode = null;}public DictSerializer(String dictCode) {super(Object.class);this.dictCode = dictCode;}@Overridepublic JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {Dict annotation = property.getAnnotation(Dict.class);if (annotation != null) {return new DictSerializer(annotation.dictCode());}return this;}@Overridepublic void serialize(Object itemCode, JsonGenerator gen, SerializerProvider provider) throws IOException {DataDictItemCache itemCache = null;if (StringUtils.isNotBlank(dictCode) && ObjectUtils.isNotEmpty(itemCode)) {DataDictItemService service = SpringUtil.getBean(DataDictItemService.class);List<DataDictItemCache> allItemCache = service.getDictItemCacheByDictCode(dictCode);if (!CollectionUtils.isEmpty(allItemCache)) {itemCache = allItemCache.stream().filter(item -> item.getItemCode().equals(itemCode)).findFirst().orElse(null);}}gen.writeObject(itemCache);}
}

相关文章:

Spring boot中实现字典管理

数据库脚本 CREATE TABLE data_dict (id bigint NOT NULL COMMENT 主键,dict_code varchar(32) DEFAULT NULL COMMENT 字典编码,dict_name varchar(64) DEFAULT NULL COMMENT 字典名称,dict_description varchar(255) DEFAULT NULL COMMENT 字典描述,dict_status tinyint DEFA…...

唯一值校验的实现思路(续)

本文接着上一篇文章《唯一值校验的实现思路》&#xff0c;在后端实现唯一值校验。用代码实现。 /*** checkUniqueException[唯一值校验]** param entity 新增或编辑的学生实体* param insert 是否新增&#xff0c;如果是传入true&#xff1b;反之传入false* return void* date…...

【AI论文】10亿参数大语言模型能超越405亿参数大语言模型吗?重新思考测试时计算最优缩放

摘要&#xff1a;测试时缩放&#xff08;Test-Time Scaling&#xff0c;TTS&#xff09;是一种通过在推理阶段使用额外计算来提高大语言模型&#xff08;LLMs&#xff09;性能的重要方法。然而&#xff0c;目前的研究并未系统地分析策略模型、过程奖励模型&#xff08;Process …...

Ubuntu20.04上搭建nginx正向代理提供上网服务

背景&#xff1a;公司很多电脑因软件管控问题不得不禁止设备上网&#xff0c;现需搭建上网代理服务器提供给这些用户使用。 操作系统&#xff1a;ubuntu20.04 工具&#xff1a;nginx-1.25.4 1、下载nginx安装包及依赖 由于nginx默认只持支持转发http协议&#xff0c;所以如…...

web前端布局--使用element中的Container布局容器

前端页面&#xff0c;跟Qt中一样&#xff0c;都是有布局设置的。 先布局&#xff0c;然后再在各布局中添加显示的内容。 Element网站布局容器&#xff1a;https://element.eleme.cn/#/zh-CN/componet/container 1.将element相应的布局容器代码layout&#xff0c;粘贴到vue项…...

使用 PDF SDK 通过页面分割和数据提取对建筑图纸进行分类

一家专门从事设计和建设的建筑公司对大量多页建筑 PDF 图纸进行分类&#xff0c;从而提高协作和运营效率。 这类公司通常承担多个建筑设计项目&#xff0c;每个项目包含多个设计图纸&#xff0c;如详细的结构计划、电气与水管计划、机械计划等。如果项目图纸可以在上传后自动分…...

Linux命名管道与共享内存

命名管道与共享内存 命名管道介绍和基本使用 理解了匿名管道后&#xff0c;命名管道的理解就会变得容易。在前面使用匿名管道时可以发现&#xff0c;之所以可以匿名是因为由父进程创建&#xff0c;子进程拷贝所以子进程和父进程都可以看到这个管道。但是如果对于任意两个进程…...

maven web项目如何定义filter

在 Maven Web 项目中定义一个 Servlet 过滤器&#xff08;Filter&#xff09;&#xff0c;需要遵循 Java Servlet 规范&#xff0c;并利用 Maven 来管理项目结构和依赖。下面是如何在 Maven Web 项目中定义和配置一个过滤器的基本步骤&#xff1a; 1. 创建过滤器类 首先&…...

使用 Notepad++ 编辑显示 MarkDown

Notepad 是一款免费的开源文本编辑器&#xff0c;专为 Windows 用户设计。它是替代记事本&#xff08;Notepad&#xff09;的最佳选择之一&#xff0c;因为它功能强大且轻量级。Notepad 支持多种编程语言和文件格式&#xff0c;并可以通过插件扩展其功能。 Notepad 是一款功能…...

@synchronized的使用

synchronized 介绍 synchronized 是 Objective-C 提供的一种 互斥锁&#xff08;Mutex&#xff09;&#xff0c;它用于确保一段代码在同一时间只有一个线程能执行&#xff0c;避免多线程访问共享资源时出现数据竞争。 基本语法 synchronized (lockObject) {// 需要加锁的代码…...

解锁Rust:融合多语言特性的编程利器

如果你曾为理解Rust的特性或它们之间的协同工作原理而苦恼,那么这篇文章正是为你准备的。 Rust拥有许多令人惊叹的特性,但这些特性并非Rust所独有。实际上,Rust巧妙地借鉴了众多其他语言的优秀特性,并将它们融合成了一个完美的整体。深入了解Rust这些重要特性的来源以及它是…...

zyNo.23

SQL注入漏洞 1.SQL语句基础知识 一个数据库由多个表空间组成&#xff0c;sql注入关系到关系型数据库&#xff0c;常见的关系型数据库有MySQL,Postgres,SQLServer,Oracle等 以Mysql为例&#xff0c;输入 mysql-u用户名-p密码 即可登录到MySQL交互式命令行界面。 既然是…...

visual studio 在kylin v10上跨平台编译时c++标准库提示缺少无法打开的问题解决

情况1&#xff1a;提示无法打开 源文件 "string"之类导致无法编译 情况2:能编译&#xff0c;但无法打开这些库文件或标准库使用提示下划红色问题 解决方案&#xff1a; 一、通过工具->选项->跨平台里&#xff0c;在“远程标头IntelliSense管理器”更新下载一下…...

黑马Mistral Le chat逆转deepseek

法国人工智能聊天机器人出来了。 Mistral AI比deepseek 性能快很多&#xff0c;准确率更高&#xff0c;非常好用。 全新的发现&#xff01; 站在老美已经出来的方法&#xff06;理论上&#xff0c;感觉有0.2亿美金和有gpu算力&#xff0c;感觉搞一个超越国内deepseek难道其实…...

Spring Cloud — 深入了解Eureka、Ribbon及Feign

Eureka 负责服务注册与发现&#xff1b;Ribbon负责负载均衡&#xff1b;Feign简化了Web服务客户端调用方式。这三个组件可以协同工作&#xff0c;共同构建稳定、高效的微服务架构。 1 Eureka 分布式系统的CAP定理&#xff1a; 一致性&#xff08;Consistency&#xff09;&am…...

Web项目测试专题(六)压力测试

概述&#xff1a; 压力测试检验Web应用在高并发、高负载情况下的表现&#xff0c;帮助预估系统承载能力和发现瓶颈 步骤&#xff1a; 并发用户测试&#xff1a;增加虚拟用户数测试系统在多人同时使用时的表现 负载测试&#xff1a;模拟高负载情况测试系统的稳定性和响应时间…...

2.5 使用注解进行单元测试详解

Mockito 使用注解进行单元测试详解 Mockito 提供了一系列注解来简化测试代码的编写&#xff0c;减少手动创建和管理 Mock 对象的样板代码。结合 JUnit 5&#xff0c;可以更高效地构建清晰、易维护的单元测试。 1. 核心注解概览 注解作用Mock创建并注入一个 Mock 对象&#xf…...

2025年SEO工具有哪些?老品牌SEO工具有哪些

随着2025年互联网的发展和企业线上营销的日益重要&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;逐渐成为了提高网站曝光率和流量的重要手段。SEO的工作不仅仅是简单地通过关键词优化和内容发布就能够实现的&#xff0c;它需要依赖一系列专业的SEO工具来帮助分析、监测和…...

使用 React 16+Webpack 和 pdfjs-dist 或 react-pdf 实现 PDF 文件显示、定位和高亮

写在前面 在本文中&#xff0c;我们将探讨如何使用 React 16Webpack 和 pdfjs-dist 或 react-pdf 库来实现 PDF 文件的显示、定位和高亮功能。这些库提供了强大的工具和 API&#xff0c;使得在 Web 应用中处理 PDF 文件变得更加容易。 项目设置 首先&#xff0c;我们需要创建…...

LabVIEW显微镜成像偏差校准

在高精度显微镜成像中&#xff0c;用户常常需要通过点击图像的不同位置&#xff0c;让电机驱动探针移动到指定点进行观察。然而&#xff0c;在实际操作中&#xff0c;经常会遇到一个问题&#xff1a;当点击位于图像中心附近的点时&#xff0c;探针能够相对准确地定位&#xff1…...

【Elasticsearch】文本分析Text analysis概述

文本分析概述 文本分析使 Elasticsearch 能够执行全文搜索&#xff0c;搜索结果会返回所有相关的结果&#xff0c;而不仅仅是完全匹配的结果。 如果你搜索“Quick fox jumps”&#xff0c;你可能希望找到包含“A quick brown fox jumps over the lazy dog”的文档&#xff0c…...

23页PDF | 国标《GB/T 44109-2024 信息技术 大数据 数据治理实施指南 》发布

一、前言 《信息技术 大数据 数据治理实施指南》是中国国家标准化管理委员会发布的关于大数据环境下数据治理实施的指导性文件&#xff0c;旨在为组织开展数据治理工作提供系统性的方法和框架。报告详细阐述了数据治理的实施过程&#xff0c;包括规划、执行、评价和改进四个阶…...

AI代码生成器如何重塑前端开发的工作环境

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术迅猛发展&#xff0c;深刻地改变着各行各业的工作方式。在软件开发领域&#xff0c;AI写代码工具的出现更是掀起了一场革命&#xff0c;尤其对前端开发工程师的工作环境和协作方式产生了深远的影响。本文将深入探讨AI…...

kafka的架构和工作原理

目录 Kafka 架构 Kafka 工作原理 Kafka 数据流 Kafka 核心特性 总结 Kafka 架构 1. 生产者(Producer) 2. 消费者(Consumer) 3. 主题(Topic) 4. 分区(Partition) 5. 副本(Replica) 6. 代理(Broker) 7. ZooKeeper(旧版本)/KRaft(新版本) Kafka 工作…...

Xcode证书密钥导入

证书干嘛用 渠道定期会给xcode证书&#xff0c;用来给ios打包用&#xff0c;证书里面有记录哪些设备可以打包进去。 怎么换证书 先更新密钥 在钥匙串访问中&#xff0c;选择系统。(选登录也行&#xff0c;反正两个都要导入就是了)。 mac中双击所有 .p12 后缀的密钥&#xff…...

索引的详细介绍

数据库索引是一种用于加速数据检索的数据结构&#xff0c;类似于书籍的目录。通过索引&#xff0c;数据库可以快速定位数据&#xff0c;而无需扫描整个表。以下是关于数据库索引的详细介绍&#xff1a; 1. 索引的基本概念 定义&#xff1a;索引是数据库表中一列或多列的值及其…...

Python 基于 OpenCV 的人脸识别上课考勤系统(附源码,部署教程)

博主介绍&#xff1a;✌2013crazy、10年大厂程序员经历。全网粉丝12W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&a…...

TikTok网页版访问受限?一文解析解决方案

TikTok网页版是许多用户用来浏览视频、管理账号和发布内容的重要工具。然而&#xff0c;部分用户可能会遇到无法打开TikTok网页版的问题&#xff0c;如页面加载失败、显示网络错误或提示访问受限。本文将帮助你快速排查问题&#xff0c;并提供解决方案&#xff0c;让你顺利访问…...

本地部署【LLM-deepseek】大模型 ollama+deepseek/conda(python)+openwebui/docker+openwebui

通过ollama本地部署deepseek 总共两步 1.模型部署 2.[web页面] 参考官网 ollama:模型部署 https://ollama.com/ open-webui:web页面 https://github.com/open-webui/open-webui 设备参考 Mac M 芯片 windows未知 蒸馏模型版本:deepseek-r1:14b 运行情况macminim2 24256 本地…...

【vs2022配置cursor】

Cursor搭配cmake实现C程序的编译、运行和调试的参考地址 cursor下载地址 第一步&#xff1a; 电脑上按爪cmake 第二步&#xff1a;cursor 配置 安装中文 第三步环境变量&#xff1a; D:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.322…...