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

RY的数据字典管理:

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

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

数据库表结构

字典类型表

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

plsql 复制代码
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_type
  unique ()
)
    comment '字典类型表';

用到了label和value.

plsql 复制代码
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 '字典数据表';

数据字典使用

在页面中获取数据字典:

vue 复制代码
<script setup>
  import {getCurrentInstance} from  'vue'   导入getCurrentInstance
  const   {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>

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

vue 复制代码
console.log(port_type.value)  //就是一个Proxy数组

原理

前端

在main.js中导入了useDict。

并进行全局的挂载。

java 复制代码
在 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中拿,没有数据再去查询后端。

javascript 复制代码
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);
  })()
}

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

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

在pinia中存储字典数据

java 复制代码
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

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

java 复制代码
@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中去。

java 复制代码
@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;
}

缓存工具类

java 复制代码
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上面添加注解,这个注解可以让项目在启动的时候加载这个方法。

java 复制代码
@PostConstruct//package javax.annotation; 这个javax的注解  加了这个注解之后 spring项目启动后会运行这个方法
public void init()
{    
    loadingDictCache();
}
java 复制代码
@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: dictType
            entry.getValue()
            .stream()
            .sorted(Comparator.comparing(SysDictData::getDictSort)) 
            .collect(Collectors.toList())
        );
    }
}
相关推荐
RainbowSea1 分钟前
6. RabbitMQ 死信队列的详细操作编写
java·消息队列·rabbitmq
RainbowSea9 分钟前
5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
java·消息队列·rabbitmq
李少兄2 小时前
Unirest:优雅的Java HTTP客户端库
java·开发语言·http
此木|西贝2 小时前
【设计模式】原型模式
java·设计模式·原型模式
可乐加.糖2 小时前
一篇关于Netty相关的梳理总结
java·后端·网络协议·netty·信息与通信
s9123601012 小时前
rust 同时处理多个异步任务
java·数据库·rust
9号达人2 小时前
java9新特性详解与实践
java·后端·面试
cg50172 小时前
Spring Boot 的配置文件
java·linux·spring boot
啊喜拔牙2 小时前
1. hadoop 集群的常用命令
java·大数据·开发语言·python·scala
anlogic3 小时前
Java基础 4.3
java·开发语言