亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

SpringBoot中實(shí)現(xiàn)數(shù)據(jù)字典的示例代碼

瀏覽:4日期:2023-04-26 13:58:31

我們在日常的項(xiàng)目開發(fā)中,對于數(shù)據(jù)字典肯定不模糊,它幫助了我們更加方便快捷地進(jìn)行開發(fā),下面一起來看看在 SpringBoot 中如何實(shí)現(xiàn)數(shù)據(jù)字典功能的

一、簡介

1、定義

數(shù)據(jù)字典是指對數(shù)據(jù)的數(shù)據(jù)項(xiàng)、數(shù)據(jù)結(jié)構(gòu)、數(shù)據(jù)流、數(shù)據(jù)存儲、處理邏輯等進(jìn)行定義和描述,其目的是對數(shù)據(jù)流程圖中的各個(gè)元素做出詳細(xì)的說明,使用數(shù)據(jù)字典為簡單的建模項(xiàng)目。簡而言之,數(shù)據(jù)字典是描述數(shù)據(jù)的信息集合,是對系統(tǒng)中使用的所有數(shù)據(jù)元素的定義的集合。

數(shù)據(jù)字典(Data dictionary)是一種用戶可以訪問的記錄數(shù)據(jù)庫和應(yīng)用程序元數(shù)據(jù)的目錄。主動數(shù)據(jù)字典是指在對數(shù)據(jù)庫或應(yīng)用程序結(jié)構(gòu)進(jìn)行修改時(shí),其內(nèi)容可以由DBMS自動更新的數(shù)據(jù)字典。被動數(shù)據(jù)字典是指修改時(shí)必須手工更新其內(nèi)容的數(shù)據(jù)字典。

2、理解

數(shù)據(jù)字典是一種通用的程序設(shè)計(jì)思想,將主體與分支存于兩張數(shù)據(jù)表中,他們之間靠著唯一的 code 相互聯(lián)系,且 code 是唯一存在的,分支依附主體而存在,每一條分支都有它唯一對應(yīng)的屬性值

例如:性別(sex),分為(0?保密1?男2?女),那么數(shù)據(jù)字典的設(shè)計(jì)就應(yīng)該是

主表:

{'code': 'sex','name': '性別'}

副表:

[{'dictCode': 'sex','code': '0','text': '保密'},{'dictCode': 'sex','code': '1','text': '男'},{'dictCode': 'sex','code': '2','text': '女'}]

那么我們在使用數(shù)據(jù)字典的時(shí)候,只需要知道 dictCode,再使用 code 找到唯一的字典值

二、數(shù)據(jù)表設(shè)計(jì)

1、數(shù)據(jù)表設(shè)計(jì)

主表:

drop table if exists sys_dict;/*==============================================================*//* Table: sys_dict *//*==============================================================*/create table sys_dict( id bigint(20) not null auto_increment comment ’主鍵id’, code varchar(32) comment ’編碼’, name varchar(32) comment ’名稱’, descript varchar(64) comment ’描述’, statustinyint(1) default 0 comment ’狀態(tài)(0--正常1--凍結(jié))’, create_time datetime comment ’創(chuàng)建時(shí)間’, create_user bigint(20) comment ’創(chuàng)建人’, del_flag tinyint(1) default 0 comment ’刪除狀態(tài)(0,正常,1已刪除)’, primary key (id))type = InnoDB;alter table sys_dict comment ’字典管理表’;

副表:

drop table if exists sys_dict_detail;/*==============================================================*//* Table: sys_dict_detail *//*==============================================================*/create table sys_dict_detail( id bigint(20) not null comment ’主鍵id’, dict_code varchar(32) comment ’字典編碼’, code varchar(32) comment ’編碼’, name varchar(32) comment ’名稱’, primary key (id))type = InnoDB;alter table sys_dict_detail comment ’字典配置表’;

它們的關(guān)系如圖所示:

SpringBoot中實(shí)現(xiàn)數(shù)據(jù)字典的示例代碼

2、數(shù)據(jù)字典配置

SpringBoot中實(shí)現(xiàn)數(shù)據(jù)字典的示例代碼

三、開發(fā)前戲

1、引入 maven 依賴

<!-- web支持 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><!-- thymeleaf模板引擎 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- aop依賴 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency><!-- lombok插件 --><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional></dependency>

我們引入了 aop 切面所需依賴,我們的數(shù)據(jù)字典也是基于 aop 切面實(shí)現(xiàn)的

2、創(chuàng)建實(shí)體類

用戶信息表 SysUserInfo.java:

import com.baomidou.mybatisplus.annotation.*;import com.baomidou.mybatisplus.extension.activerecord.Model;import com.zyxx.common.annotation.Dict;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;import lombok.EqualsAndHashCode;import lombok.experimental.Accessors;import java.io.Serializable;/** * <p> * 用戶信息表 * </p> * * @author lizhou * @since 2020-07-06 */@Data@EqualsAndHashCode(callSuper = false)@Accessors(chain = true)@TableName('sys_user_info')@ApiModel(value='SysUserInfo對象', description='用戶信息表')public class SysUserInfo extends Model<SysUserInfo> { @ApiModelProperty(value = 'ID') @TableId(value = 'id', type = IdType.AUTO) private Long id; @ApiModelProperty(value = '登錄賬號') @TableField('account') private String account; @ApiModelProperty(value = '登錄密碼') @TableField('password') private String password; @ApiModelProperty(value = '姓名') @TableField('name') private String name; @ApiModelProperty(value = '性別(0--未知1--男2--女)') @TableField('sex') @Dict(dictCode = 'sex') private Integer sex; @ApiModelProperty(value = '狀態(tài)(0--正常1--凍結(jié))') @TableField('status') @Dict(dictCode = 'status') private Integer status;}

3、返回結(jié)果通用實(shí)體類

返回結(jié)果通用實(shí)體類 LayTableResult.java:

import lombok.Getter;import lombok.Setter;import java.util.List;/** * @param <T> 返回的實(shí)體類 * @author lizhou * @描述 后臺返回給LayUI的數(shù)據(jù)格式 */@Getter@Setterpublic class LayTableResult<T> { /** * 接口狀態(tài) */ private Integer code; /** * 提示信息 */ private String msg; /** * 接口數(shù)據(jù)長度 */ private Long count; /** * 接口數(shù)據(jù) */ private List<T> data; /** * 無參構(gòu)造函數(shù) */ public LayTableResult() { super(); } /** * 返回?cái)?shù)據(jù)給表格 */ public LayTableResult(Long count, List<T> data) { super(); this.count = count; this.data = data; this.code = 0; }}

由于我用的是 layui 前端框架,我寫了一個(gè)返給 layui 表格的通用實(shí)體類,這是在實(shí)現(xiàn)數(shù)據(jù)字典需要用到的,判斷響應(yīng)返回實(shí)體類的類型來判斷是否需要注入字典

四、開發(fā)實(shí)現(xiàn)

1、創(chuàng)建自定義注解

我們創(chuàng)建一個(gè)自定義注解 @Dict 來實(shí)現(xiàn)數(shù)據(jù)字典

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 數(shù)據(jù)字典注解 * * @author Tellsea * @date 2020/6/23 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Dict { /** * 字典類型 * * @return */ String dictCode(); /** * 返回屬性名 * * @return */ String dictText() default '';}

2、注解實(shí)現(xiàn)

我們使用 aop 切面來實(shí)現(xiàn)什么的自定義注解 @Dict

import com.alibaba.fastjson.JSONObject;import com.fasterxml.jackson.annotation.JsonFormat;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import com.zyxx.common.annotation.Dict;import com.zyxx.common.utils.LayTableResult;import com.zyxx.common.utils.ObjConvertUtils;import com.zyxx.sbm.entity.SysDictDetail;import com.zyxx.sbm.service.SysDictService;import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang3.StringUtils;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.lang.reflect.Field;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;/** * 數(shù)據(jù)字典切面 * * @author Tellsea * @date 2020/6/23 */@Aspect@Component@Slf4jpublic class DictAspect {/*** 字典后綴*/ private static String DICT_TEXT_SUFFIX = 'Text'; @Autowired private SysDictService sysDictService;/*** 切點(diǎn),切入 controller 包下面的所有方法*/ @Pointcut('execution( * com.zyxx.*.controller.*.*(..))') public void dict() { } @Around('dict()') public Object doAround(ProceedingJoinPoint pjp) throws Throwable { long time1 = System.currentTimeMillis(); Object result = pjp.proceed(); long time2 = System.currentTimeMillis(); log.debug('獲取JSON數(shù)據(jù) 耗時(shí):' + (time2 - time1) + 'ms'); long start = System.currentTimeMillis(); this.parseDictText(result); long end = System.currentTimeMillis(); log.debug('解析注入JSON數(shù)據(jù) 耗時(shí)' + (end - start) + 'ms'); return result; } private void parseDictText(Object result) { if (result instanceof LayTableResult) { List<JSONObject> items = new ArrayList<>(); LayTableResult rr = (LayTableResult) result; if (rr.getCount() > 0) {List<?> list = (List<?>) rr.getData();for (Object record : list) { ObjectMapper mapper = new ObjectMapper(); String json = '{}'; try { // 解決@JsonFormat注解解析不了的問題詳見SysAnnouncement類的@JsonFormat json = mapper.writeValueAsString(record); } catch (JsonProcessingException e) { log.error('Json解析失敗:' + e); } JSONObject item = JSONObject.parseObject(json); // 解決繼承實(shí)體字段無法翻譯問題 for (Field field : ObjConvertUtils.getAllFields(record)) { //解決繼承實(shí)體字段無法翻譯問題 // 如果該屬性上面有@Dict注解,則進(jìn)行翻譯 if (field.getAnnotation(Dict.class) != null) { // 拿到注解的dictDataSource屬性的值 String dictType = field.getAnnotation(Dict.class).dictCode(); // 拿到注解的dictText屬性的值 String text = field.getAnnotation(Dict.class).dictText(); //獲取當(dāng)前帶翻譯的值 String key = String.valueOf(item.get(field.getName())); //翻譯字典值對應(yīng)的text值 String textValue = translateDictValue(dictType, key); // DICT_TEXT_SUFFIX的值為,是默認(rèn)值: // public static final String DICT_TEXT_SUFFIX = '_dictText'; log.debug('字典Val: ' + textValue); log.debug('翻譯字典字段:' + field.getName() + DICT_TEXT_SUFFIX + ': ' + textValue); //如果給了文本名 if (!StringUtils.isBlank(text)) {item.put(text, textValue); } else {// 走默認(rèn)策略item.put(field.getName() + DICT_TEXT_SUFFIX, textValue); } } // date類型默認(rèn)轉(zhuǎn)換string格式化日期 if ('java.util.Date'.equals(field.getType().getName())&& field.getAnnotation(JsonFormat.class) == null&& item.get(field.getName()) != null) { SimpleDateFormat aDate = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss'); item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName())))); } } items.add(item);}rr.setData(items); } } } /** * 翻譯字典文本 * * @param dictType * @param key * @return */ private String translateDictValue(String dictType, String key) { if (ObjConvertUtils.isEmpty(key)) { return null; } StringBuffer textValue = new StringBuffer(); String[] keys = key.split(','); for (String k : keys) { if (k.trim().length() == 0) {continue; } /** * 根據(jù) dictCode 和 code 查詢字典值,例如:dictCode:sex,code:1,返回:男 * 應(yīng)該放在redis,提高響應(yīng)速度 */ SysDictDetail dictData = sysDictService.getDictDataByTypeAndValue(dictType, key); if (dictData.getName() != null) {if (!''.equals(textValue.toString())) { textValue.append(',');}textValue.append(dictData.getName()); } log.info('數(shù)據(jù)字典翻譯: 字典類型:{},當(dāng)前翻譯值:{},翻譯結(jié)果:{}', dictType, k.trim(), dictData.getName()); } return textValue.toString(); }}

3、注解使用

我們只需要在實(shí)體類的屬性上加入我們實(shí)現(xiàn)的自定義注解即可

@ApiModelProperty(value = '性別(0--未知1--男2--女)')@TableField('sex')@Dict(dictCode = 'sex')private Integer sex;@ApiModelProperty(value = '狀態(tài)(0--正常1--凍結(jié))')@TableField('status')@Dict(dictCode = 'status')private Integer status;

我們對 sex,status 都加入了 @Dict(dictCode = “”) 注解,那么我們在獲取用戶信息的時(shí)候,就能獲取到對應(yīng)的字典值了

五、測試

1、編寫 API 查詢

我們在 controller 層開放一個(gè) API 實(shí)現(xiàn)查詢用戶列表

/** * 分頁查詢 */@PostMapping('list')@ResponseBodypublic LayTableResult list(Integer page, Integer limit, SysUserInfo userInfo) { QueryWrapper<SysUserInfo> queryWrapper = new QueryWrapper<>(); if (StringUtils.isNotBlank(userInfo.getName())) { queryWrapper.like('name', userInfo.getName()); } if (null != userInfo.getSex()) { queryWrapper.eq('sex', userInfo.getSex()); } if (null != userInfo.getStatus()) { queryWrapper.eq('status', userInfo.getStatus()); } queryWrapper.orderByDesc('create_time'); IPage<SysUserInfo> iPage = sysUserInfoService.page(new Page<>(page, limit), queryWrapper); return new LayTableResult<>(iPage.getTotal(), iPage.getRecords());}

注意: 這里我們使用了 LayTableResult 作為相應(yīng)實(shí)體類,與上面我們編寫的返回通用實(shí)體類是一致的,必須一直,才能實(shí)現(xiàn)數(shù)據(jù)字典功能

2、調(diào)用 API

返回結(jié)果如下:

{'code': 0,'msg': null,'count': 3,'data': [{'id': 2,'account': '15286779045','name': '周杰倫','sex': 1,'sexText': '男','status': 0,'statusText': '正常'}, {'id': 1,'name': '超級管理員','account': '15286779044','sex': 1,'sexText': '男','status': 0,'statusText': '正常'}]}

可以看出,返回的數(shù)據(jù)中,多出了 sexText,statusText,兩個(gè)屬性,也就證明我們的字典功能已經(jīng)實(shí)現(xiàn)成功

六、總結(jié)

1、優(yōu)點(diǎn)

1、在一定程度上,通過系統(tǒng)維護(hù)人員即可改變系統(tǒng)的行為(功能),不需要開發(fā)人員的介入。使得系統(tǒng)的變化更快,能及時(shí)響應(yīng)客戶和市場的需求。2、提高了系統(tǒng)的靈活性、通用性,減少了主體和屬性的耦合度 3、簡化了主體類的業(yè)務(wù)邏輯 4、能減少對系統(tǒng)程序的改動,使數(shù)據(jù)庫、程序和頁面更穩(wěn)定。特別是數(shù)據(jù)量大的時(shí)候,能大幅減少開發(fā)工作量5、使數(shù)據(jù)庫表結(jié)構(gòu)和程序結(jié)構(gòu)條理上更清楚,更容易理解,在可開發(fā)性、可擴(kuò)展性、可維護(hù)性、系統(tǒng)強(qiáng)壯性上都有優(yōu)勢。

2、缺點(diǎn)

1、數(shù)據(jù)字典是通用的設(shè)計(jì),在系統(tǒng)效率上會低一些。2、程序算法相對復(fù)雜一些。3、對于開發(fā)人員,需要具備一定抽象思維能力,所以對開發(fā)人員的要求較高。

3、優(yōu)化

我們的數(shù)據(jù)字典數(shù)據(jù)應(yīng)該存放在 redis 中,減少與數(shù)據(jù)庫的交互次數(shù),提高響應(yīng)速度

到此這篇關(guān)于SpringBoot中實(shí)現(xiàn)數(shù)據(jù)字典的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot 數(shù)據(jù)字典內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 女人被免费视频网站 | 免费一级a毛片在线 | 久久久国产99久久国产一 | 国产偷国产偷亚洲高清在线 | 国产视频观看 | 久久久久一级片 | 欧美日韩亚洲国内综合网俺 | www.91久久 | 亚洲黄色美女 | 黄色毛片看看 | 91啪在线观看国产在线 | 国产精品久久久久一区二区 | 欧美a在线视频 | 伊人久久精品线影院 | 福利视频不卡 | 黑人艹| 亚洲高清免费在线观看 | 国产精品美女在线观看 | 久久久青草青青亚洲国产免观 | 在线观看国产小屁孩cao大人 | 国精视频一区二区视频 | 黄色片aaa | 成人免费观看国产高清 | 2021精品综合久久久久 | 美女黄网站人色视频免费国产 | 国产精选91热在线观看 | 黄色网址免费 | 中文字幕在亚洲第一在线 | 欧美一级一一特黄 | 亚洲综合精品一二三区在线 | 久久青青草原国产精品免费 | 在线观看a级片 | 一本伊大人香蕉在线观看 | 欧美日韩大尺码免费专区 | 国产成综合 | 国产欧美一区二区三区久久 | 国产成人影院一区二区 | 成人国产一区二区 | 成人精品视频 | 亚洲国产成人精彩精品 | 澳门久久 |