springboot启动读取数据字典缓存到redis实现方式

 更新时间:2026年03月12日 14:26:30   作者:Filwaod  
文章描述了如何通过增加数据字典表和使用Redis缓存来简化数据库查询返回值的转换过程,并提供了一些代码示例和配置说明

因数据库中存的都是数字(数据字典),但是又没有数据字典表,只有后端知道是什么意思,查询返回给前端时,需要if-else进行转换成具体的值,很麻烦,现增加数据字典表,通过redis获取,转换成具体的值

1.建表

CREATE TABLE `data_dictionary`  (
  `id` bigint(20) NOT NULL COMMENT '主键id',
  `module` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '归属模块',
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '字典名',
  `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '字典编码',
  `value` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '字典取值',
  `order` int(3) NOT NULL DEFAULT -1 COMMENT '排序',
  `state` tinyint(1) NOT NULL DEFAULT -1 COMMENT '启用状态 0:停用 1:启用',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
)ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '数据字典表';

2.mybatisplus生成controller,service,mapper,do等

下面是用到的DO,VO

@Data
@TableName("data_dictionary")
@ApiModel(value="DataDictionaryDO对象", description="数据字典表")
public class DataDictionaryDO implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "主键id")
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    @ApiModelProperty(value = "归属模块")
    private String module;

    @ApiModelProperty(value = "字典名")
    private String name;

    @ApiModelProperty(value = "字典编码")
    private String code;

    @ApiModelProperty(value = "字典取值")
    private String value;

    @ApiModelProperty(value = "排序")
    private Integer sort;

    @ApiModelProperty(value = "启用状态 0:停用 1:启用")
    private Integer state;

    @ApiModelProperty(value = "创建时间")
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date createTime;

}

@Data
@ApiModel(value = "DateDictionaryVo对象", description = "数据字典Vo")
@ToString
public class DataDictionaryVo implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "字典编码")
    private String code;

    @ApiModelProperty(value = "字典取值")
    private String value;

    @ApiModelProperty(value = "redis key")
    private String key;

}

3.数据字典常量

/**
 * @description:数据字典常量
 */
public class DataDictionaryConstant {

    /**
     * redis中数据字典key
     */
    public static final String DATA_DICTIONARY_KEY = "dataDictionary";

    /**
     * 合同-执行状态
     */
    public static final String CONTRACT_STATUS = "contract:status";
}

4.redis配置

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        // 创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置连接工厂
        template.setConnectionFactory(connectionFactory);
        // 创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // 设置Key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置Value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        // 返回
        return template;
    }
}

5.实现springboot启动查询数据字典表

将数据缓存到redis中,使用@PostConstruct注解

/**
 * @description:项目启动初始化数据字典到redis
 */
@Slf4j
@Component
public class InitConfig {

    @Autowired
    private DataDictionaryMapper  dataDictionaryMapper;
    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @PostConstruct
    public void initDataDictionary() {
        log.info("初始数据字典信息-开始");
        if (Boolean.TRUE.equals(redisTemplate.hasKey(DATA_DICTIONARY_KEY))) {
            redisTemplate.delete(DATA_DICTIONARY_KEY);
        }
        List<DataDictionaryDO> dictionaryDOList = dataDictionaryMapper.selectList(null);
        Map<String, List<DataDictionaryVo>> dataMap = dictionaryDOList.stream().map(obj -> {
            DataDictionaryVo dataDictionaryVo = new DataDictionaryVo();
            dataDictionaryVo.setCode(obj.getCode());
            dataDictionaryVo.setValue(obj.getValue());
            dataDictionaryVo.setKey(obj.getModule() + ":" + obj.getName());
            return dataDictionaryVo;
        }).collect(Collectors.groupingBy(DataDictionaryVo::getKey));
        redisTemplate.opsForHash().putAll(DATA_DICTIONARY_KEY, dataMap);
        log.info("初始数据字典信息-结束");
    }
}

6.往表中插入几条数据

再启动项目,看效果

7.redis中查看

可以看到redis在序列化对象时,把类信息(@class)也序列化进来了,这样存的作用是反序列化时知道反序列化成什么对象,但是浪费了内存空间;不想存类信息的话,需要手动序列化成字符串再存进来,获取时再手动反序列成对象,看你怎么选择了

8.将获取封装成一个工具方法

方便调用

@Service
public class RedisService {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 缓存中查数据字典
     * @param key redis key
     * @param code  字典编码
     * @return
     */
    public String getDataDictionary(String key, String code) {
        String value = null;
        if (Boolean.TRUE.equals(redisTemplate.hasKey(DATA_DICTIONARY_KEY))) {
            List<DataDictionaryVo> dataDictionary = (List<DataDictionaryVo>) redisTemplate
                .opsForHash().get(DATA_DICTIONARY_KEY, key);
            if (dataDictionary.size() > 0) {
                value = dataDictionary.stream().filter(obj -> code.equals(obj.getCode()))
                    .findFirst().get().getValue();
            }
        }
        return value != null ? value : "";
    }

}

为什么要这么写

Boolean.TRUE.equals(redisTemplate.hasKey(key))

而不是

redisTemplate.hasKey(DATA_DICTIONARY_KEY)

这是因为idea提示可能会出现空指针,然后查资料修改成上面的写法:https://www.jb51.net/program/36014522y.htm

9.使用

//使用
String value = redisService.getDataDictionary(CONTRACT_STATUS, "0");
System.out.println(value);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • springCloud服务注册Eureka实现过程图解

    springCloud服务注册Eureka实现过程图解

    这篇文章主要介绍了springCloud服务注册Eureka实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java布隆过滤器的应用实例

    Java布隆过滤器的应用实例

    这篇文章主要介绍了Java布隆过滤器的应用实例,在程序的世界中,布隆过滤器是程序员的一把利器,利用它可以快速地解决项目中一些比较棘手的问题,如网页 URL 去重、垃圾邮件识别、大集合中重复元素的判断和缓存穿透等问题,需要的朋友可以参考下
    2023-11-11
  • 在非Spring管理对象中注入Spring Bean的解决方案

    在非Spring管理对象中注入Spring Bean的解决方案

    在SpringBoot开发中,我们习惯了通过@Autowired/@Resource等注解轻松注入依赖 Bean,但在WebSocket、定时任务等场景下,会遇到一个核心问题:非Spring创建的对象无法直接注入 Spring Bean,所以本文给大家介绍了在非Spring管理对象中注入Spring Bean的解决方案
    2026-02-02
  • Java实现文本编译器

    Java实现文本编译器

    这篇文章主要为大家详细介绍了Java实现文本编译器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • 详解Eclipse 字体、字号的设置、最佳字体推荐

    详解Eclipse 字体、字号的设置、最佳字体推荐

    这篇文章主要介绍了Eclipse 字体、字号的设置、最佳字体推荐,需要的朋友可以参考下
    2020-09-09
  • mybatis-plus报错net.sf.jsqlparser.statement.select.SelectBody的问题解决

    mybatis-plus报错net.sf.jsqlparser.statement.select.SelectBody的

    本文主要介绍了mybatis-plus报错net.sf.jsqlparser.statement.select.SelectBody的问题解决,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08
  • SpringBoot获取application.properties文件中文乱码问题及解决

    SpringBoot获取application.properties文件中文乱码问题及解决

    这篇文章主要介绍了SpringBoot获取application.properties文件中文乱码问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Java中BIO、NIO和AIO的区别、原理与用法

    Java中BIO、NIO和AIO的区别、原理与用法

    这篇文章主要介绍了Java中BIO、NIO和AIO的区别、原理与用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • 浅谈Strut2如何对请求参数的封装

    浅谈Strut2如何对请求参数的封装

    这篇文章主要介绍了浅谈Strut2如何对请求参数的封装,具有一定借鉴价值,需要的朋友可以参考下
    2017-12-12
  • Java8 新特性之日期时间对象及一些其他特性

    Java8 新特性之日期时间对象及一些其他特性

    这篇文章主要介绍了Java8 新特性之日期时间对象及一些其他特性,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01

最新评论