成人视屏在线观看-国产99精品-国产精品1区2区-欧美一级在线观看-国产一区二区日韩-色九九九

您的位置:首頁技術文章
文章詳情頁

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

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

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

一、簡介

1、定義

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

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

2、理解

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

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

主表:

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

副表:

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

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

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

1、數(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--凍結)’, create_time datetime comment ’創(chuàng)建時間’, 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 ’字典配置表’;

它們的關系如圖所示:

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

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

SpringBoot中實現(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 切面實現(xiàn)的

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

用戶信息表 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--凍結)') @TableField('status') @Dict(dictCode = 'status') private Integer status;}

3、返回結果通用實體類

返回結果通用實體類 LayTableResult.java:

import lombok.Getter;import lombok.Setter;import java.util.List;/** * @param <T> 返回的實體類 * @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; /** * 無參構造函數(shù) */ public LayTableResult() { super(); } /** * 返回數(shù)據(jù)給表格 */ public LayTableResult(Long count, List<T> data) { super(); this.count = count; this.data = data; this.code = 0; }}

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

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

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

我們創(chuàng)建一個自定義注解 @Dict 來實現(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、注解實現(xiàn)

我們使用 aop 切面來實現(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;/*** 切點,切入 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ù) 耗時:' + (time2 - time1) + 'ms'); long start = System.currentTimeMillis(); this.parseDictText(result); long end = System.currentTimeMillis(); log.debug('解析注入JSON數(shù)據(jù) 耗時' + (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); // 解決繼承實體字段無法翻譯問題 for (Field field : ObjConvertUtils.getAllFields(record)) { //解決繼承實體字段無法翻譯問題 // 如果該屬性上面有@Dict注解,則進行翻譯 if (field.getAnnotation(Dict.class) != null) { // 拿到注解的dictDataSource屬性的值 String dictType = field.getAnnotation(Dict.class).dictCode(); // 拿到注解的dictText屬性的值 String text = field.getAnnotation(Dict.class).dictText(); //獲取當前帶翻譯的值 String key = String.valueOf(item.get(field.getName())); //翻譯字典值對應的text值 String textValue = translateDictValue(dictType, key); // DICT_TEXT_SUFFIX的值為,是默認值: // 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 {// 走默認策略item.put(field.getName() + DICT_TEXT_SUFFIX, textValue); } } // date類型默認轉換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,返回:男 * 應該放在redis,提高響應速度 */ SysDictDetail dictData = sysDictService.getDictDataByTypeAndValue(dictType, key); if (dictData.getName() != null) {if (!''.equals(textValue.toString())) { textValue.append(',');}textValue.append(dictData.getName()); } log.info('數(shù)據(jù)字典翻譯: 字典類型:{},當前翻譯值:{},翻譯結果:{}', dictType, k.trim(), dictData.getName()); } return textValue.toString(); }}

3、注解使用

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

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

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

五、測試

1、編寫 API 查詢

我們在 controller 層開放一個 API 實現(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 作為相應實體類,與上面我們編寫的返回通用實體類是一致的,必須一直,才能實現(xiàn)數(shù)據(jù)字典功能

2、調用 API

返回結果如下:

{'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,兩個屬性,也就證明我們的字典功能已經(jīng)實現(xiàn)成功

六、總結

1、優(yōu)點

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

2、缺點

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

3、優(yōu)化

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

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

標簽: Spring
相關文章:
主站蜘蛛池模板: 伊人色综合久久天天网蜜月 | 一级做a爱片特黄在线观看免费看 | 成人a视频片在线观看免费 成人a视频在线观看 | 国产美女91视频 | 国产孕妇孕交视频 | 久久99精品综合国产首页 | 欧美一区二区三区免费高 | 日本又黄又爽又免费 | 视频一区色眯眯视频在线 | 美女大片高清特黄a大片 | 国产的一级毛片完整 | 久久精品国产只有精品2020 | 日韩一区二区三区在线免费观看 | 国产视频一区二区三区四区 | 亚洲一区二区三区四区五区六区 | 亚洲视频天堂 | 精品国产高清毛片 | 成人国产精品一区二区网站 | 国产成人精品高清在线观看99 | 在线99| 日本网址在线观看 | 午夜爽爽爽男女免费观看hd | 日本www在线播放 | 国产成年人视频 | 国产欧美久久久精品影院 | 免费国产成人 | 欧美日韩一区二区在线视频 | 欧美α一级毛片 | 国产区二区 | 免费观看欧美精品成人毛片 | 国产深夜福利视频网站在线观看 | 免费精品99久久国产综合精品 | 深夜福利国产福利视频 | 亚洲91| 国产人成久久久精品 | 91大神大战丝袜美女在线观看 | 国产精品青草久久 | 欧美一级片在线 | 99视频有精品 | 九九久久精品这里久久网 | 成人夜色视频网站在线观看 |