Redis在SpringBoot中的使用

在SpringBoot项目中使用redis存储数据作为字典

本项目使用jdk1.8

一、添加依赖

复制代码
<!-- spring boot redis缓存引入 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 缓存连接池-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

<!-- redis 存储 json序列化 -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

二、配置yml

复制代码
#spring: 
  redis:
    host: 公网IP
    port: 6379
    database: 0
    password: (redis密码) #默认为空
    timeout: 3000ms #最大等待时间,超时则抛出异常,否则请求一直等待
    lettuce:
      pool:
        max-active: 20  #最大连接数,负值表示没有限制,默认8
        max-wait: -1    #最大阻塞等待时间,负值表示没限制,默认-1
        max-idle: 8     #最大空闲连接,默认8
        min-idle: 0     #最小空闲连接,默认0

三、写配置类

3.1 为什么写配置类

如果不写配置类,那么往redis存值,会存jdk序列化的数据,无法正常观看数据

3.2 配置类

java 复制代码
package com.atguigu.srb.base.config;

@Configuration
public class RedisConfig {


    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        //首先解决key的序列化方式
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);

        //解决value的序列化方式
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

        //序列化时将类的数据类型存入json,以便反序列化的时候转换成正确的类型
        ObjectMapper objectMapper = new ObjectMapper();
        //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);

        // 解决jackson2无法反序列化LocalDateTime的问题
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);


        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
}

四、测试

4.1 存值

java 复制代码
/**
 * FileName: RedisTemplateTest
 * Author: ccy
 * Description:redis测试
 * Date:   2025/4/21 22:23
 */
@SpringBootTest(classes = ServiceCoreApplication.class)
@RunWith(SpringRunner.class)
public class RedisTemplateTest {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private DictMapper dictMapper;

    @Test
    public void saveDict() {
        Dict dict = dictMapper.selectById(1);
        //向数据库中存储string类型的键值对,过期时间5分钟
        redisTemplate.opsForValue().set("dict", dict, 5 , TimeUnit.MINUTES);
    }

}

发现RedisTemplate默认使用了JDK的序列化方式存储了key和value

4.2 取值

java 复制代码
package com.atguigu.srb;

/**
 * FileName: RedisTemplateTest
 * Author: ccy
 * Description:redis测试
 * Date:   2025/4/21 22:23
 */
@SpringBootTest(classes = ServiceCoreApplication.class)
@RunWith(SpringRunner.class)//
public class RedisTemplateTest {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private DictMapper dictMapper;


    @Test
    public void getDict() {
        Dict dict = (Dict)redisTemplate.opsForValue().get("dict");
        System.out.println(dict);

    }

}

五、将数据字典存入Redis

本项目功能实际应用于尚融宝项目

java 复制代码
 // ---------Controller---------

    /**
     * 延迟加载
     * @param parentId 前台传后台参数
     * @return R
     */
    @ApiOperation("根据上级id获取子节点数据列表")
    @GetMapping("/listByParentId/{parentId}")
    public R listByParentId(@ApiParam(value = "上级节点id", required = true)
                                @PathVariable Long parentId) {
        List<Dict> dictList = dictService.listByParentId(parentId);
        return R.ok().data("list", dictList);
    }

// --------ServiceImpl-----------

@Override
    public List<Dict> listByParentId(Long parentId) {

        //用try-catch的原因是redis调用可能出错
        try {

            //首先查询redis中是否存在数据列表
            List<Dict> dictList = (List<Dict>)         redisTemplate.opsForValue().get("srb:core:dictList" + parentId);

            //如果存在,则从redis中直接返回数据列表
            if (dictList != null) {
                log.info("从redis中获取数据列表");
                return dictList;
            }

        } catch (Exception e) {
            //ExceptionUtils.getStackTrace(e): 拿到e对象错误跟踪栈字符串
            log.error("redis服务器异常:" + ExceptionUtils.getStackTrace(e));
        }

        // 如果不存在,则从数据库中查询,并把数据保存到redis中
        log.info("从数据库中获取数据列表");
        LambdaQueryWrapper<Dict> qW = Wrappers.lambdaQuery();
        qW.eq(Dict::getParentId, parentId);
        List<Dict> dictList = this.list(qW);
        //填充hashChildren字段
        dictList.forEach(dict -> {
            //判断当前节点是否有子节点,找到当前的dict下级是否有子节点
            boolean hasChildren = this.hasChildren(dict.getId());
            dict.setHasChildren(hasChildren);
        });

        try {
            //将数据存入redis
            log.info("将数据存入redis");
            redisTemplate.opsForValue().set("srb:core:dictList" + parentId, dictList, 5, TimeUnit.MINUTES);
        } catch (Exception e) {
            log.error("redis服务器异常:" + ExceptionUtils.getStackTrace(e));
        }

        //返回数据列表
        return dictList;
    }
相关推荐
snow@li37 分钟前
Spring Boot:项目服务器完整部署教程(零基础可直接实操)
服务器·spring boot·后端
学计算机的计算基1 小时前
操作系统内存管理全解:虚拟内存、页表、COW、malloc、OOM一篇搞定
java·笔记·算法
流星白龙1 小时前
【Redis】1.Redis特性
数据库·redis·缓存
tachibana21 小时前
hot100 前 K 个高频元素(347)
java·数据结构·算法·leetcode
万亿少女的梦1681 小时前
基于Spring Boot、Java与MySQL的网络订餐系统设计与实现
java·spring boot·mysql·系统设计·网络订餐
咩咩啃树皮10 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
鱟鲥鳚10 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
大模型码小白12 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司13 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地13 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码