Skip to content

数据字典

在业务开发中,数据字典是我们管理关键数据特征的核心工具。它不仅确保了数据的一致性和可维护性,还促进了团队成员之间的有效沟通与协作。通过数据字典,我们能够更高效地维护和更新数据,减少错误和误解,从而提高决策的准确性。

与传统的数据库备注维护相比,使用数据字典进行管理更加高效和及时。它提供了一个集中的平台,使得数据更新和维护更加迅速和准确,从而提升了整个团队的工作效率和数据管理的质量。

字典管理

字典由 字典类型字典项 构成:

在设计之初的思考:我们并不关心字典的具体值是什么,需要明确那个key对应那个value即可,因此无论是字典类型、还是字典项其ID都是由自定义自增规则来生成的,无需用户关心。

规则如下:字典类型 有不同的业务类型:系统字典和业务字典,系统字典起始号段为1000自增,业务字典的(默认)起始号段为2000自增。

字典项ID = 字典类型ID(四位)+(三位自增编号构成,不足位置补零)

字典构成

字典由 字典类型字典项 构成:

设计初衷

在设计数据字典时,我们的核心理念是简化用户的操作流程。我们认识到,在大多数情况下,用户更关心的是字典中键(key)与值(value)之间的对应关系,而非具体的值内容。因此,我们设计了一套自动的ID生成机制,使得字典类型和字典项的ID都是根据自定义的自增规则自动生成的,这样用户就无需手动干预ID的分配,从而降低了操作复杂性。

此外,为了满足一些特殊场景下的需求,我们还提供了设置唯一别名的功能,以便用户可以根据实际情况对字典项进行标识和区分。

规则说明

  • 字典类型 有不同的业务类型:系统字典和业务字典。

    • 系统字典起始号段为 1000 自增。
    • 业务字典的(默认)起始号段为 2000 自增。
  • 字典项ID = 字典类型ID(四位)+(三位自增编号构成,不足位置补零)

NOTE

假设我们有一个系统字典类型,其ID为1001,那么其下的字典项ID可能是:

  • 1001001
  • 1001002
  • 1001003
  • ...

实际应用场景

在框架开发过程中,我们深入考虑了实际应用场景,以确保数据字典能够满足不同业务需求。

字典的迁移

在系统升级过程中,数据字典的更新是一个关键步骤,需要精心设计的迁移脚本来确保数据的平滑过渡。为了简化这一过程,我们的系统提供了字典SQL预览功能。这一功能可以帮助开发者快速构建迁移脚本。

动态字典

除了传统的静态字典,我们还特别考虑了业务动态性的需求,引入了动态字典的概念。这种字典能够根据业务的实时变化自动更新,例如:

  • 用户信息动态字典:包含用户ID、用户名称等信息,这些信息会随着用户的增加、修改或删除而动态变化。
  • 产品信息动态字典:随着新产品的添加或旧产品的淘汰,产品信息会不断更新。

用户可以根据自己的业务需求,利用系统提供的接口和规范,创建和管理这些动态字典。这种动态字典的设计,使得数据管理更加灵活和实时,能够快速响应业务变化,提高系统的适应性和响应速度。

动态字典的构建过程
java
/**
 * DictLoader接口
 *
 * @ClassName DictLoader
 * @Author sz
 * @Date 2024/8/21 9:06
 * @Version 1.0
 */
public interface DictLoader {

    /**
     * 返回带有前缀的动态 typeCode
     *
     * @return 带有前缀的 typeCode
     */
    DynamicDictEnum getDynamicTypeCode();

    /**
     * 加载所有字典数据,以 Map 结构返回。
     *
     * @return 字典数据的 Map,key 是 typeCode,value 是字典列表 DictCustomVO
     */
    Map<String, List<DictVO>> loadDict();

    /**
     * 根据typeCode获取Dict
     * 
     * @param typeCode
     *            类型
     * @return DictCustomVO集合
     */
    default List<DictVO> getDict(String typeCode) {
        return loadDict().get(typeCode);
    }

}

系统用户动态字典示例

java
/**
 * 动态字典——系统用户loader
 *
 * @ClassName DynamicUserOptionDictLoader
 * @Author sz
 * @Date 2024/8/21 13:17
 * @Version 1.0
 */
@Component
@RequiredArgsConstructor
public class UserOptionDictLoader implements DictLoader {

 private final RedisCache redisCache;

 private final SysUserService sysUserService;

 @Override
 public DynamicDictEnum getDynamicTypeCode() {
     return DynamicDictEnum.DYNAMIC_USER_OPTIONS;
 }

 @Override
 public Map<String, List<DictVO>> loadDict() {
     String key = getDynamicTypeCode().getTypeCode();
     String name = getDynamicTypeCode().getName();
     if (redisCache.hasHashKey(key)) {
         return Map.of(key, redisCache.getDictByType(key));
     }

     DictVO dictVO;
     List<DictVO> list = new ArrayList<>();
     List<UserOptionVO> userOptions = sysUserService.getUserOptions();
     for (int i = 0; i < userOptions.size(); i++) {
         UserOptionVO option = userOptions.get(i);
         dictVO = DictVO.builder().id(option.getId().toString()).codeName(option.getNickname()).alias(option.getUsername()).sort(i + 1).sysDictTypeCode(key)
                 .sysDictTypeName(name).callbackShowStyle("primary").isDynamic(true).isLock("F").isShow("T").build();
         list.add(dictVO);
     }
     redisCache.setDict(key, list);
     return Map.of(key, list);
 }

 @Override
 public List<DictVO> getDict(String typeCode) {
     return loadDict().get(typeCode);
 }

}

场景

1. Table、Excel的展示

表格中显示的数据可以根据字典关联项自动将值(value)转换为对应的键(key)表示。例如,如果一个字段存储的是核对状态Code码(“1000001”),而我们希望在表格中展示的是状态名(“正常、异常”),系统会自动查找并转换,从而提供更直观、更易理解的数据展示。

dict-table-column

dict-excel-column

2. 编辑页面选择

在编辑页面,字典提供了一个选择机制。用户可以直接从下拉菜单中选择当前有效的字典项。

dict-edit

3. 代码生成器与字典关联设置

我们的代码生成器支持与字典的关联设置。可以通过简单的配置,将字典与代码生成器关联,从而自动生成与字典关联的代码。这不仅减少了手动编码的工作量,还确保了代码的准确性和及时性。

dict-generator