若依框架--数据字典设计使用和前后端代码分析

server/2025/1/15 17:17:52/

RY的数据字典管理:

字典管理是用来维护数据类型的数据,如下拉框、单选按钮、复选框、树选择的数据,方便系统管理员维护。减少对后端的访问,原来的下拉菜单点击一下就需要对后端进行访问,现在通过数据字典减少了对后端的访问。

如果不使用数据字典,对于每次查找的一些字段都要向后端发送请求。比如选择的时候 下拉框,因为数据都是动态选择的,不能直接输入。这样开发起来效率会很低。

数据库表结构

字典类型表

包括了 类型名称 、 字典类型需要是英文,status状态/

create table sys_dict_type
(dict_id     bigint auto_increment comment '字典主键'primary key,dict_name   varchar(100) default ''  null comment '字典名称',dict_type   varchar(100) default ''  null comment '字典类型',status      char         default '0' null comment '状态(0正常 1停用)',create_by   varchar(64)  default ''  null comment '创建者',create_time datetime                 null comment '创建时间',update_by   varchar(64)  default ''  null comment '更新者',update_time datetime                 null comment '更新时间',remark      varchar(500)             null comment '备注',constraint dict_typeunique ()
)comment '字典类型表';

用到了label和value.

create table sys_dict_data
(dict_code   bigint auto_increment comment '字典编码'primary key,dict_sort   int          default 0   null comment '字典排序',dict_label  varchar(100) default ''  null comment '字典标签',dict_value  varchar(100) default ''  null comment '字典键值',dict_type   varchar(100) default ''  null comment '字典类型',css_class   varchar(100)             null comment '样式属性(其他样式扩展)',list_class  varchar(100)             null comment '表格回显样式',is_default  char         default 'N' null comment '是否默认(Y是 N否)',status      char         default '0' null comment '状态(0正常 1停用)',create_by   varchar(64)  default ''  null comment '创建者',create_time datetime                 null comment '创建时间',update_by   varchar(64)  default ''  null comment '更新者',update_time datetime                 null comment '更新时间',remark      varchar(500)             null comment '备注'
)comment '字典数据表';

数据字典使用

在页面中获取数据字典:

<script setup>import {getCurrentInstance} from  'vue'   导入getCurrentInstanceconst   {proxy}=getCurrentInstance()const {port_type} =proxy.useDict('port_type')   //通过UseDict获取数据字典</script><template><div  v-for="item in port_type" :key="item.value" >{{item.label}}:{{item.value}}</div>
</template>

页面加载的时候像后端发送数据字典的请求。

console.log(port_type.value)  //就是一个Proxy数组

原理

前端

在main.js中导入了useDict。

并进行全局的挂载。

Vue 3 中,app.config.globalProperties 是一个可以让我们在 全局 为应用添加自定义属性或方法的对象。它的作用大致相当于 Vue 2 时代的 Vue.prototype。当我们执行:、
app.config.globalProperties.useDict = useDict
实际上就是给整个 Vue 应用的实例注入了一个名为 useDict 的方法,使得在任何组件实例里,都能够通过 this.useDict(在 Options API)或 proxy.useDict(在 Composition API 中通过 getCurrentInstance() 获取)去调用它。

拿到所有的数据字典。根据传进来的参数进行遍历字典,返回数据。

UseDictStore,对于某个页面的数据字典,会拿到之后存入到pinia中去,先看pinia中有没有数据,如果有就从pinia中拿,没有数据再去查询后端。

import useDictStore from '@/store/modules/dict'
import { getDicts } from '@/api/system/dict/data'/**
* 获取字典数据
*/
export function useDict(...args) {const res = ref({});return (() => {args.forEach((dictType, index) => {res.value[dictType] = [];const dicts = useDictStore().getDict(dictType);if (dicts) {res.value[dictType] = dicts;} else {getDicts(dictType).then(resp => {res.value[dictType] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass }))useDictStore().setDict(dictType, res.value[dictType]);})}})return toRefs(res.value);})()
}

向后端发送数据字典请求的代码

export function getDicts(dictType) {return request({url: '/system/dict/data/type/' + dictType,method: 'get'})
}

在pinia中存储字典数据

const useDictStore = defineStore('dict',{state: () => ({dict: new Array()}),
actions: {// 获取字典getDict(_key) {if (_key == null && _key == "") {return null;}try {for (let i = 0; i < this.dict.length; i++) {if (this.dict[i].key == _key) {return this.dict[i].value;}}} catch (e) {return null;}},// 设置字典setDict(_key, value) {if (_key !== null && _key !== "") {this.dict.push({key: _key,value: value});}},// 删除字典removeDict(_key) {var bln = false;try {for (let i = 0; i < this.dict.length; i++) {if (this.dict[i].key == _key) {this.dict.splice(i, 1);return true;}}} catch (e) {bln = false;}return bln;},// 清空字典cleanDict() {this.dict = new Array();},// 初始字典initDict() {}
}
})export default useDictStore

持久化之后页面再次回来,不会发送请求了,而是直接从pinia中获取数据。

后端

在admin包下面 sysDictDataController

根据数据字典类型查询数据

@GetMapping(value = "/type/{dictType}")
public AjaxResult dictType(@PathVariable String dictType)
{List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);if (StringUtils.isNull(data)){data = new ArrayList<SysDictData>();}return success(data);
}

这边代码做了一个缓存的操作,每次启动项目的时候都会将数据查询所有的数据字典,缓存到redis中去。

@Override
public List<SysDictData> selectDictDataByType(String dictType)
{
List<SysDictData> dictDatas = DictUtils.getDictCache(dictType); //拿到缓存的字典
if (StringUtils.isNotEmpty(dictDatas))
{return dictDatas;
}
dictDatas = dictDataMapper.selectDictDataByType(dictType); //根据dictType查询数据库
if (StringUtils.isNotEmpty(dictDatas))
{DictUtils.setDictCache(dictType, dictDatas);return dictDatas;
}
return null;
}

缓存工具类

public static List<SysDictData> getDictCache(String key)
{
//拿到一个一个JSON树,将JSon数组转为List集合
JSONArray arrayCache = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
if (StringUtils.isNotNull(arrayCache))
{return arrayCache.toList(SysDictData.class);
}
return null;
}/*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public <T> T getCacheObject(final String key){ValueOperations<String, T> operation = redisTemplate.opsForValue();return operation.get(key);}public static String getCacheKey(String configKey){return CacheConstants.SYS_DICT_KEY + configKey;}public static final String SYS_DICT_KEY = "sys_dict:";

查看Redis缓存,发现存在数据字典

删除redis中的数据字典,重新启动项目。发现数据字典又出来,说明项目启动的时候自动回去查询数据字典

在SysDictTypeServiceImpl上面添加注解,这个注解可以让项目在启动的时候加载这个方法。

@PostConstruct//package javax.annotation; 这个javax的注解  加了这个注解之后 spring项目启动后会运行这个方法
public void init()
{    loadingDictCache();
}
@Override
public void loadingDictCache()
{// 1. 构造一个条件对象(SysDictData),并设置 status = "0"SysDictData dictData = new SysDictData();dictData.setStatus("0");// 2. 查询数据库中符合条件(status = "0")的字典数据,然后使用 Stream 流处理Map<String, List<SysDictData>> dictDataMap = dictDataMapper.selectDictDataList(dictData)    // 2.1 从数据库中获取所有的字典数据.stream()                        // 2.2 转换为 Stream.collect(                        // 2.3 分组Collectors.groupingBy(SysDictData::getDictType));// 3. 遍历每一组字典数据(以 dictType 作为分组依据)for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet()){// 4. 按照某个排序字段(getDictSort)对每个分组内的字典数据进行排序,然后放进缓存DictUtils.setDictCache(entry.getKey(), // key: dictTypeentry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)) .collect(Collectors.toList()));}
}

http://www.ppmy.cn/server/158111.html

相关文章

性能测试工具Jmeter中的FTP脚本开发

FTP文件传输协议是TCP/IP协议组织中的常用协议之一&#xff0c;主要用在internet上双向传输文件。FTP协议具有客户端和服务器端两个部分组成部分&#xff0c;具有上传与下载两种功能。Jmeter也提供了FTP请求的测试支持&#xff0c;实现了上传和下载功能测试。 对于上图的FTP请求…

小白项目部署:anaconda环境+pycharm+yolov5(虚拟机环境)

创建虚拟环境&#xff1a;conda create --name my_yolo 激活环境命令&#xff1a;activate my_yolo 3.打开anaconnda软件&#xff0c;选择my_yolo环境 4.点击右下角&#xff0c;更换pycharm虚拟环境my_yolo 5.选择Conda环境&#xff0c;选择my_yolo 6.安装解释器成功 7.…

HTTP 入门:认识网络通信基础

一、引言&#xff1a;HTTP 在网络世界的基石地位 在当今数字化的时代&#xff0c;网络通信如同空气一般无处不在&#xff0c;而 HTTP 协议则是网络世界中最为重要的基石之一。无论是浏览网页、使用手机 APP&#xff0c;还是进行各种网络数据交互&#xff0c;HTTP 都在背后默默…

C++ Primer Notes(4): 变量初始化和作用域

这篇笔记是关于 C Primer 的 2.2 节 Variables 的记录和思考。 1. 变量是什么 变量是有名字的对象&#xff1a; variables are named objects. 那么什么是对象&#xff08;object&#xff09;&#xff1f; 一块具有类型的内存&#xff0c;称为对象。 而没有名字的对象&#…

Java-数据结构-链表(LinkedList)-双向链表

一、LinkedList(无头双向链表) 在之前的学习中&#xff0c;我们已经学习过"单向链表"并通过做题加深了对"单向链表"的认知&#xff0c;而今天我们继续来学习链表&#xff0c;也就是"无头双向链表"~ 在了解"无头双向链表"之前&#x…

用户界面软件04

后果 使用这种架构很容易对两个层面的非功能性需求进行优化&#xff0c;但是你仍然需要小心不要将功能 需求重复实现。 现在&#xff0c;两个层面可能有完全不同的设计。比如&#xff0c;用户界面层可能使用配件模型&#xff08;Widget Model&#xff09;&#xff0c; 以大量的…

OpenCV基础:视频的采集、读取与录制

从摄像头采集视频 相关接口 - VideoCapture VideoCapture 用于从视频文件、摄像头或其他视频流设备中读取视频帧。它可以捕捉来自多种源的视频。 主要参数&#xff1a; cv2.VideoCapture(source): source: 这是一个整数或字符串&#xff0c;表示视频的来源。 如果是整数&a…

JS进阶--JS听到了探囊的回响

深浅拷贝 深拷贝 开发中我们经常需要复制一个对象&#xff0c;如果直接用赋值会有下面的问题 深浅拷贝只针对引用类型&#xff0c;深拷贝拷贝的是对象&#xff0c;不是地址 常见方法&#xff1a; 1. 通过递归实现深拷贝 2. lodash/cloneDeep 3. 通过JSON.stringify()实现…