MySQL表设计---字典表的设计与接口实现
https://i-blog.csdnimg.cn/blog_migrate/fead7f31405aafbe631917936cd25b74.png1、字典表的意义
假设有一个职员表:
姓名性别证件范例学历国籍甲男身份证本科中国乙女身份证本科中国…………… 这个表有一亿条数据,现在用户要求证件范例要从"身份证"改为"居民身份证",这样一下更新全部数据,能完成,但维护困难,由此,思量这么实现:
代号身份证范例001身份证002暂住证 加了这样一个身份证范例表后,职员表变为:
姓名性别证件范例学历国籍甲男001本科中国乙女001本科中国…………… 此时把"身份证"改为"居民身份证",只需改身份证范例表的一行数据的一个字段。但此时有新的问题了,国籍、学历也是可以罗列完的字段,那再加个学历范例表?显然不行,如果这种字段有十几个,那以后查询就要进行几十个表的联结(join)操作。先看实现:
系统代码表标识分类内容111Country中国112Country美国………………001ID身份证002ID暂住证 即加一个范例字段,以区分是具体哪个字段的。
2、若依的字典表结构
基于以上一个简单的背景,来看若依框架提供的字典表结构:ruoyi有两张字典相干表,一个字典范例表sys_dict_type,一个字典数据表sys_dict_data,将字典定义和数据分开。先看字典范例表:
https://i-blog.csdnimg.cn/blog_migrate/8a57e2c5a0bd12baf998fa15f9b647d9.png
https://i-blog.csdnimg.cn/blog_migrate/e61719468ec4576db76a5c94e2dec188.png
再看字典数据表:
https://i-blog.csdnimg.cn/blog_migrate/341b174cbc333c1fbb2e26e41a923697.png
https://i-blog.csdnimg.cn/blog_migrate/83487e3ba25fcae2cffd2f8c0fd7dc14.png
[*]两张表通过字典范例字段dict_type关联
[*]字典数据表中有顺序字段dict_sort,可调解罗列对应表现顺序
[*]字典数据表有键和值字段,页面表现值dict_label,数据库中存代号dict_value
[*]两张表都有status字段控制整条数据是否可用
字典数据表支持层级也是一个要思量的点,如下面这个需求:
https://i-blog.csdnimg.cn/blog_migrate/20c9b96744093b3d5ced6b6cc3d2bcab.png
此时,可以增加一个parent_id可以在数据表中递归查询全部的层级数据:
https://i-blog.csdnimg.cn/blog_migrate/b861a72cfdc09872964caa36174b8d11.png
这个需求的实现,参考:https://blog.csdn.net/llg___/article/details/129683540
3、ruoyi罗列类
字典中定义好数据了,再写一个对应于dict_type的罗列类,罗列类中定义值,方便背面代码中调用罗列值做业务处置惩罚。以ruoyi的审核状态字典为例:
https://i-blog.csdnimg.cn/blog_migrate/87b5df37920919020b7d0f29efd5fbe9.png
罗列类定义:
import brave.internal.Nullable;
import java.util.HashMap;
import java.util.Map;
public enum AuditStatusEnum {
BEFORE("before","待提交"),
WAIT("wait", "待审核"),
NO("no", "审核未通过"),
PASS("pass","审核通过");
String code;
String name;
AuditStatusEnum(String code, String name) {
this.code = code;
this.name = name;
}
private static final Map<String, AuditStatusEnum> mappings = new HashMap<>(5);
static {
for (AuditStatusEnum statusEnum : values()) {
mappings.put(statusEnum.code, statusEnum);
}
}
public String getCode(){
return code;
}
public String getName(){
return name;
}
@Nullable
public static AuditStatusEnum resolve(@Nullable String code) {
return (code != null ? mappings.get(code) : null);
}
}
[*]values()方法作用是获取罗列成员的全部值,返回一个数组
[*]写静态代码块,以罗列值的code为键,以罗列值本身为值创建Map聚集
[*]末了的静态方法resolve()则是根据罗列值的code查询罗列值
[*]这里是利用了Java类加载的机会之一:访问类的静态方法,执行静态代码块,初始化Map方便背面查询,妙!
关于Java类加载的机会,访问这里。
/定义了上面的字典对应的枚举类后,写业务逻辑代码:
if (xxDto.getAuditCode().equals(AuditStatusEnum.NO.getCode())){
return new MyException("审核未通过,不可操作!");
}
4、代码.ruoyi字典查询接口与缓存
定义接口,查询差别范例下的字典的key和value,给前端展示(固然前端也可以用html定义下拉框选项写死几个)
/**
* 根据字典类型查询字典数据信息
*/
@GetMapping(value = "/type/{dictType}")
public AjaxResult dictType(@PathVariable String dictType) {
return AjaxResult.success(dictTypeService.selectDictDataByType(dictType));
}
service层接口:
/**
* 根据字典类型查询字典数据
*
* @param dictType 字典类型
* @return 字典数据集合信息
*/
public List<SysDictData> selectDictDataByType(String dictType);
service接口实现类:这里是先在字典缓存中查,如果有,直接返回,如果缓存中没有,则调mapper层去数据库查,并把结果查询结果写进缓存备用
/**
* 根据字典类型查询字典数据
*
* @param dictType 字典类型
* @return 字典数据集合信息
*/
@Override
public List<SysDictData> selectDictDataByType(String dictType) {
List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
if (StringUtils.isNotNull(dictDatas)) {
return dictDatas;
}
dictDatas = dictDataMapper.selectDictDataByType(dictType);
if (StringUtils.isNotNull(dictDatas)) {
DictUtils.setDictCache(dictType, dictDatas);
return dictDatas;
}
return null;
}
获取字典缓存的方法定义:
/**
* 获取字典缓存
*
* @param key 参数键
* @return dictDatas 字典数据列表
*/
public static List<SysDictData> getDictCache(String key)
{
Object cacheObj = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key));
if (StringUtils.isNotNull(cacheObj))
{
List<SysDictData> dictDatas = StringUtils.cast(cacheObj);
return dictDatas;
}
return null;
}
此时,前端调用接口,传入对应的dictType,即可拿到下拉框中的字典字段:
https://i-blog.csdnimg.cn/blog_migrate/76d39a50dab5d0a42d2f21c82900fcc9.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]