日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

SpringBoot中實現數據字典的示例代碼

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

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

一、簡介

1、定義

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

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

2、理解

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

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

主表:

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

副表:

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

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

二、數據表設計

1、數據表設計

主表:

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 ’狀態(0--正常1--凍結)’, create_time datetime comment ’創建時間’, create_user bigint(20) comment ’創建人’, del_flag tinyint(1) default 0 comment ’刪除狀態(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中實現數據字典的示例代碼

2、數據字典配置

SpringBoot中實現數據字典的示例代碼

三、開發前戲

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 切面所需依賴,我們的數據字典也是基于 aop 切面實現的

2、創建實體類

用戶信息表 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 = '狀態(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的數據格式 */@Getter@Setterpublic class LayTableResult<T> { /** * 接口狀態 */ private Integer code; /** * 提示信息 */ private String msg; /** * 接口數據長度 */ private Long count; /** * 接口數據 */ private List<T> data; /** * 無參構造函數 */ public LayTableResult() { super(); } /** * 返回數據給表格 */ public LayTableResult(Long count, List<T> data) { super(); this.count = count; this.data = data; this.code = 0; }}

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

四、開發實現

1、創建自定義注解

我們創建一個自定義注解 @Dict 來實現數據字典

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

2、注解實現

我們使用 aop 切面來實現什么的自定義注解 @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;/** * 數據字典切面 * * @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數據 耗時:' + (time2 - time1) + 'ms'); long start = System.currentTimeMillis(); this.parseDictText(result); long end = System.currentTimeMillis(); log.debug('解析注入JSON數據 耗時' + (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; } /** * 根據 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('數據字典翻譯: 字典類型:{},當前翻譯值:{},翻譯結果:{}', dictType, k.trim(), dictData.getName()); } return textValue.toString(); }}

3、注解使用

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

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

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

五、測試

1、編寫 API 查詢

我們在 controller 層開放一個 API 實現查詢用戶列表

/** * 分頁查詢 */@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 作為相應實體類,與上面我們編寫的返回通用實體類是一致的,必須一直,才能實現數據字典功能

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': '正常'}]}

可以看出,返回的數據中,多出了 sexText,statusText,兩個屬性,也就證明我們的字典功能已經實現成功

六、總結

1、優點

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

2、缺點

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

3、優化

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

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

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久精品国产亚洲夜色av网站| 视频在线在亚洲| 日本免费一区二区视频| 亚洲无线观看| 麻豆久久精品| 蘑菇福利视频一区播放| 国产美女一区| 男人的天堂久久精品| 亚洲男女自偷自拍| 夜夜嗨网站十八久久| 丝袜av一区| 久久久久亚洲| 狠狠色狠狠色综合日日tαg| 国产精品美女久久久浪潮软件| 香蕉久久国产| 婷婷综合一区| 久久激情五月婷婷| 国产精品成人3p一区二区三区| 麻豆精品视频在线观看| 久久99国产精品视频| 激情综合五月| 欧美不卡高清一区二区三区| 99国产精品一区二区| 欧美 日韩 国产精品免费观看| 精品一区在线| 婷婷丁香综合| 日韩在线卡一卡二| 日韩亚洲精品在线观看| 国产精品永久| 在线手机中文字幕| 图片区亚洲欧美小说区| 石原莉奈在线亚洲三区| 欧美精品国产| 日韩成人三级| 丝袜a∨在线一区二区三区不卡| 18国产精品| 韩国久久久久久| 久久午夜精品| 老司机精品视频在线播放| 日韩精品首页| 亚洲深深色噜噜狠狠爱网站| 毛片不卡一区二区| 亚洲国产不卡| 欧美成a人片免费观看久久五月天| 久久婷婷激情| 日韩激情网站| 亚洲综合在线电影| 日精品一区二区三区| 黄色在线观看www| 日韩中文字幕91| 国产成人精品一区二区三区在线| 午夜欧美视频| 92国产精品| 美女网站久久| 国产一区二区精品福利地址| 美女久久久久久| 99久久精品费精品国产| 在线亚洲一区| 国产精品a级| 国产99久久久国产精品成人免费| 亚洲一区亚洲| 日韩视频一二区| 久久永久免费| 欧美va天堂在线| 亚久久调教视频| 久久久久久久久成人| 久久久久国产| 亚洲精品裸体| 久久精品日韩欧美| 欧洲av不卡| 在线精品视频一区| 国产极品一区| 久久伦理在线| 911亚洲精品| 久久激情网站| 日本va欧美va欧美va精品| 黑森林国产精品av| 亚洲欧美视频一区二区三区| 国产精品主播| 亚洲v在线看| 亚洲精品极品| 国产精品探花在线观看| 国产午夜久久| 国产精品欧美日韩一区| 国产在线日韩| 91嫩草精品| 久久久人人人| 欧美亚洲tv| 99热精品久久| 国产美女亚洲精品7777| 久久久久中文| 国产欧美日韩视频在线| 伊人久久大香线蕉av不卡| 免费精品视频最新在线| 欧美aⅴ一区二区三区视频| 亚洲视频国产精品| 日韩精品永久网址| 日韩高清一区二区| 亚洲a在线视频| 国产精品一区二区免费福利视频| 日本精品影院| 欧美久久香蕉| 欧美精品自拍| 精品国产亚洲一区二区三区| 亚洲综合日韩| 成人福利视频| 国产日韩一区二区三区在线播放| 日韩亚洲国产欧美| 日韩黄色大片| 日本精品在线播放| 在线看片日韩| 亚洲第一精品影视| 久久精品天堂| 日韩av一区二| 免费视频久久| 天堂√8在线中文| 久久国产精品免费一区二区三区| 91精品91| 久久久久久一区二区| 欧美天堂在线| 日本 国产 欧美色综合| 亚洲欧美日本日韩| 欧美日韩在线网站| 国产一区二区三区黄网站| 日本午夜精品视频在线观看| 乱人伦精品视频在线观看| 日韩欧美自拍| 国产成人免费精品| 国产精品4hu.www| 91欧美极品| 亚洲欧美视频一区二区三区| 久久久一本精品| 麻豆精品国产91久久久久久| 欧美激情在线精品一区二区三区| 亚洲精品伊人| 在线一区二区三区视频| 婷婷综合网站| 日韩精品专区| 国产一区二区三区不卡视频网站 | 国产精品tv| 亚洲精品日韩久久| 亚洲专区欧美专区| 亚洲一级特黄| 国产专区一区| 欧美日韩精品免费观看视完整| 久久精品国产999大香线蕉| 青青草国产成人99久久| 午夜久久影院| 综合精品一区| 亚洲免费成人av在线| 亚洲综合图色| 亚洲另类av| 日韩在线麻豆| 久久国产精品久久久久久电车| 一区在线视频观看| 亚洲女同一区| 亚洲免费观看| 蜜桃久久av| 爽好多水快深点欧美视频| 久久国产成人| 亚洲精品系列| 亚洲精品婷婷| 欧美在线看片| 麻豆91小视频| 日本欧美不卡| 影音先锋国产精品| 中文一区一区三区免费在线观 | 国产精品午夜一区二区三区| 国产亚洲精品精品国产亚洲综合| 国产毛片一区二区三区| 国产精品mv在线观看| 久久精品人人| 久久久一本精品| 欧美99久久| 丝袜亚洲另类欧美 | 国产在视频一区二区三区吞精| 精品丝袜久久| 高清不卡亚洲| 免费av一区| 中文字幕视频精品一区二区三区| 在线免费观看亚洲| 日韩国产一二三区| 色综合视频一区二区三区日韩 | 精品国产亚洲一区二区在线观看| 狠狠久久伊人中文字幕| 日本在线啊啊| 欧美网站在线| 91国内精品| 黄毛片在线观看| 欧美特黄视频| 日韩精品午夜视频| 精品中国亚洲| 欧美福利专区| 中文字幕一区二区精品区| 婷婷亚洲综合| 一区二区不卡| 天堂中文av在线资源库| 亚洲精品中文字幕乱码| 日韩激情一二三区| 精品一区二区三区中文字幕|