如何将枚举转换成字典实现动态的效果

Posted 赵晓东-Nastu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将枚举转换成字典实现动态的效果相关的知识,希望对你有一定的参考价值。

场景

一般我们在做系统的时候都会遇到枚举的情况,但是发现如果我们再进行添加会修改原来的类,那么怎么实现动态的添加呢?

数据库的设计

类型长度注释
idint11
keychar32编码
valuevarchar255
typechar64字典类型
sortint11排序
delete_flagtinyint4
create_timedatetime0
update_timedatetime0

实体设计

@Data
@EqualsAndHashCode(callSuper = false)
public class CrmDictionary implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 编码
     */
    private String key;

    /**
     * 值
     */
    private String value;

    /**
     * 字典类型
     */
    private String type;

    /**
     * 排序
     */
    private Integer sort;

    private Integer deleteFlag;

    private LocalDateTime createTime;

    private LocalDateTime updateTime;


}

Service设计

@Slf4j
@Service
public class CrmDictionaryServiceImpl extends ServiceImpl<CrmDictionaryMapper, CrmDictionary> implements CrmDictionaryService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CrmDictionaryMapper crmDictionaryMapper;

    private static Map<String, String> keyValueMap = new HashMap<>();

    private static Map<String, String> valueKeyMap = new HashMap<>();

    /**
     * 加载 crm_dictionary 字典表数据
     *
     * @author guoshuaipo
     * @date  2021/10/19 14:07
     * @param
     * @return
     */
    @PostConstruct
    private void initDicInfosourceData() {
        List<CrmDictionary> list = crmDictionaryMapper.getAllDict();
        if (list.size()>0){
            Map<String, List<CrmDictionary>> listMap = list.stream().collect(Collectors.groupingBy(CrmDictionary::getType));
            for (Map.Entry<String, List<CrmDictionary>> entry : listMap.entrySet()) {
                String type = entry.getKey();
                entry.getValue().stream().forEach(e -> {
                    keyValueMap.put(RedisKeyPrefixEnum.CRM_DICTIONARY_HKEY.getPrefix()+type+e.getKey(), e.getValue());
                    valueKeyMap.put(RedisKeyPrefixEnum.CRM_DICTIONARY_HKEY.getPrefix()+type+e.getValue(), e.getKey());
//                    redisTemplate.opsForValue().set(RedisKeyPrefixEnum.CRM_DICTIONARY_HKEY.getPrefix()+type+"-"+e.getKey(), e.getValue());
//                    redisTemplate.opsForValue().set(RedisKeyPrefixEnum.CRM_DICTIONARY_HKEY.getPrefix()+type+"-"+e.getValue(), e.getKey());
                });
            }
        }else {
            log.warn("=================crm_dictionary字典数据初始化时为空===================");
        }
    }

    @Override
    public String getValueByCode(String type, String code){
        if (code==null){
            return null;
        }
        // Object val = redisTemplate.opsForValue().get(RedisKeyPrefixEnum.CRM_DICTIONARY_HKEY.getPrefix()+type+"-"+code);
        String val = keyValueMap.get(RedisKeyPrefixEnum.CRM_DICTIONARY_HKEY.getPrefix() + type + code);
        if (val!=null){
            return val;
        }else {
            log.warn("未能根据code找到相应字典value数据,type:{},code:{}", type,code);
            return null;
        }
    }

    @Override
    public String getValueByCode(String type, Integer code){
        return getValueByCode(type, String.valueOf(code));
    }

    @Override
    public String getStringCodeByValue(String type, String value){
        if (value==null){
            return null;
        }
//        Object val = redisTemplate.opsForValue().get(RedisKeyPrefixEnum.CRM_DICTIONARY_HKEY.getPrefix()+type+"-"+value);
        String val = valueKeyMap.get(RedisKeyPrefixEnum.CRM_DICTIONARY_HKEY.getPrefix() + type + value);
        if (val!=null){
            return val;
        }else {
            log.warn("未能根据value找到相应字典code数据,type:{},value:{}", type,value);
            return null;
        }
    }

    @Override
    public Integer getIntegerCodeByValue(String type, String value){
        return Integer.valueOf(getStringCodeByValue(type, value));
    }

    @Override
    public List<CrmDictionary> getDictDateByType(String type) {
        return crmDictionaryMapper.getDictDateByType(type);
    }
}

RedisKeyPrefixEnum

@Getter
public enum RedisKeyPrefixEnum {
    /*
     * 字典数据前缀
     */
    CRM_DICTIONARY_HKEY("crm-dictionary-")
    ;
    private final String prefix;

    RedisKeyPrefixEnum(String prefix) {
        this.prefix = prefix;
    }
}

Mapper查询

    <select id="getAllDict" resultType="com.hc360.crm.entity.po.CrmDictionary">
        SELECT
            `key`,
            `value`,
            `type`,
            sort
        FROM
            crm_dictionary
        WHERE
            (delete_flag = 0)
        ORDER BY
            type ASC,
            sort ASC
    </select>
    <select id="getDictDateByType" resultType="com.hc360.crm.entity.po.CrmDictionary">
        SELECT
            `key`,
            `value`,
            sort
        FROM
            crm_dictionary
        WHERE
            (delete_flag = 0) and `type`=#{type}
        ORDER BY
            sort ASC
    </select>
</mapper>

总结

这样我们就可以实现动态的字典固定值设计了,可以优化一点将查询出来的字典值存入到Redis里面。

以上是关于如何将枚举转换成字典实现动态的效果的主要内容,如果未能解决你的问题,请参考以下文章

C#如何将枚举类(enum)型转换成字符(string)类型

C#如何将枚举类(enum)型转换成字符(string)类型

Python代码阅读(第26篇):将列表映射成字典

如何将此 JavaScript 代码片段翻译成 Parenscript?

java 如何将String 转换成 枚举

将字符串数组转换为WHERE子句中的自定义枚举类型