Redis在Spring Boot中的应用

Redis作为一种常见的noSQL数据库,凭借其卓越的性能成为了常用的缓存中间件,本文将介绍如何通过Java代码操作Redis数据库以及如何使用Spring Cache这个轻量便捷的缓存框架

Spring Data Redis

在Spring Boot项目中,我们常借助Spring Data Redis便捷地实现对Redis数据库的操作

1.首先,导入 Spring Data Redis 的依赖:

xml 复制代码
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-data-redis</artifactId>  
</dependency>

2.接着,在配置文件中完成对数据源的配置(与MySQL类似)

xml 复制代码
spring:  
  redis:  
    host: localhost(已经配置好Redis的主机的IP)
    password: (如果没有密码可以删除这一行)
    port: 6379  
    database: 0 (要操作哪一个数据库,默认为0)

3.编写配置类,创建RedisTemplate对象

由于Spring Data Redis 会采用 JdkSerializationRedisSerializer (基于 JDK 序列化)来序列化存入 Redis 的值,这就会导致原本清晰明了的字符串变成让人看不懂的二进制乱码。因此我们需要手动配置RedisTemplate,将 key 的序列化器改为 StringRedisSerializer,提高数据的可读性。

java 复制代码
@Slf4j  
@Configuration  
public class RedisConfigration {  
    @Bean  
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){  
        log.info("创建Redis模板对象...");  
        RedisTemplate redisTemplate = new RedisTemplate();  
        //设置Redis连接工厂对象  
        redisTemplate.setConnectionFactory(redisConnectionFactory);  
        //设置Redis的key的序列化器  
        redisTemplate.setKeySerializer(new StringRedisSerializer());  
        return redisTemplate;  
    }  
}

先通过 @Bean 注解在 Spring 容器中注册一个名为 redisTemplateRedisTemplate 实例,然后将自动注入的 RedisConnectionFactory 赋值给该模板,确保它能正确连接到 Redis 服务器,接着,就是显示设置key的序列化器,确保key以纯字符串的形式储存起来。

效果对比: 将手动设置StringRedisSerializer序列化器注释掉时,可以看到在纯字符串的key前面多了许多二进制乱码

设置之后key就一目了然 由于没有设置value的序列化器(也没有必要设置),所以注释前后value的值都是一大串乱码。

4.通过RedisTemplate对象操作Redis

java 复制代码
//获取操作每种类型的对象
public void getRedisOperations(){  
  
    ValueOperations valueOperations = redisTemplate.opsForValue();  
    HashOperations hashOperations = redisTemplate.opsForHash();  
    ListOperations listOperations = redisTemplate.opsForList();  
    SetOperations setOperations = redisTemplate.opsForSet();  
    ZSetOperations zSetOperations = redisTemplate.opsForZSet();  
  
}

如果要多次操作同一种数据类型的数据,可以通过以上方法获取对应的操作对象,减少性能的开销。但如果不是这样的情景,就可以直接链式编程来操作Redis,相关语法如下:

java 复制代码
// 键操作命令
redisTemplate.keys(pattern);                 // KEYS pattern - 查找所有符合模式的 key
redisTemplate.hasKey(key);                   // EXISTS key - 检查 key 是否存在
redisTemplate.type(key);                     // TYPE key - 返回 key 储存值的类型
redisTemplate.delete(key);                   // DEL key - 删除指定的 key
redisTemplate.expire(key, timeout, timeUnit); // EXPIRE key seconds - 设置过期时间
redisTemplate.getExpire(key);                // TTL key - 获取剩余生存时间

// 字符串类型命令
redisTemplate.opsForValue().set(key, value);  // SET key value
redisTemplate.opsForValue().get(key);         // GET key
redisTemplate.opsForValue().set(key, value, timeout, timeUnit); // SETEX key seconds value
redisTemplate.opsForValue().setIfAbsent(key, value); // SETNX key value

// 哈希类型命令
redisTemplate.opsForHash().put(key, field, value);  // HSET key field value
redisTemplate.opsForHash().get(key, field);         // HGET key field
redisTemplate.opsForHash().delete(key, field);      // HDEL key field
redisTemplate.opsForHash().keys(key);               // HKEYS key
redisTemplate.opsForHash().values(key);             // HVALS key

// 列表类型命令
redisTemplate.opsForList().leftPush(key, value);     // LPUSH key value
redisTemplate.opsForList().range(key, start, end);   // LRANGE key start stop
redisTemplate.opsForList().rightPop(key);            // RPOP key
redisTemplate.opsForList().size(key);                // LLEN key

// 集合类型命令
redisTemplate.opsForSet().add(key, members);          // SADD key member
redisTemplate.opsForSet().members(key);               // SMEMBERS key
redisTemplate.opsForSet().size(key);                  // SCARD key
redisTemplate.opsForSet().intersect(key, otherKeys);  // SINTER key1 key2
redisTemplate.opsForSet().union(key, otherKeys);      // SUNION key1 key2
redisTemplate.opsForSet().remove(key, members);       // SREM key member

// 有序集合类型命令
redisTemplate.opsForZSet().add(key, member, score);   // ZADD key score member
redisTemplate.opsForZSet().range(key, start, end);    // ZRANGE key start stop
redisTemplate.opsForZSet().incrementScore(key, member, delta); // ZINCRBY key increment member
redisTemplate.opsForZSet().remove(key, members);      // ZREM key member

Spring Cache

不难发现,虽然通过Spring Data Redis可以便捷的操作Redis,但是在实际项目中应用到Redis缓存,肯定少不了 查询缓存中是否有需要的数据 : 有,直接返回缓存数据 无,查询MySQL -> 将结果保存到redis 这一繁琐的过程。

那有没有更简单更无脑的办法呢?Spring Cache就将这些过程进行了封装,通过相关注解轻松实现数据缓存:

这里以@Cacheable为例说明如何使用

应用场景:

java 复制代码
@GetMapping("/list")  
@ApiOperation("根据分类id查询套餐")  
@Cacheable(value = "setmealCache", key = "#categoryId")  
public Result<List<Setmeal>> list(Long categoryId) {  
    Setmeal setmeal = new Setmeal();  
    setmeal.setCategoryId(categoryId);  
    setmeal.setStatus(StatusConstant.ENABLE);  
  
    List<Setmeal> list = setmealService.list(setmeal);  
    return Result.success(list);  
}

该注解的value和key属性共同决定了最终的缓存键 value指定了缓存的名称,便于管理和区分不同类型的缓存数据。key指定了缓存的键生成规则,这里使用# + 变量就可以动态赋值 最终缓存键为value::key

其余两个注解的value和key属性与此同理。

需要注意的是,当我们对数据进行修改,删除,新增时一定要使用@CacheEvict清除缓存,确保数据的一致性。

相关推荐
浅念-2 小时前
C++ STL vector
java·开发语言·c++·经验分享·笔记·学习·算法
亓才孓2 小时前
[Mybatis]MyBatisSystemException(由于Connection的encoding引起的)
java·开发语言·mybatis
_OP_CHEN2 小时前
【Linux系统编程】(三十四)初识进程信号:Linux 软中断的核心奥秘
linux·后端·操作系统·进程·信号·终端信号
Never_Satisfied2 小时前
在c#中,如何在字符串的第x个字符位置插入字符
java·开发语言·c#
晔子yy2 小时前
AI编程时代:发挥Rules约束在Vibe-Coding的重要作用
开发语言·人工智能·后端
夏乌_Wx2 小时前
从零开始实现一个自己的 Shell:mybash 项目实战
linux·c语言·后端
m0_531237172 小时前
C语言-while循环,continue/break,getchar()/putchar()
java·c语言·算法
kong79069282 小时前
SpringBoot原理
java·spring boot·后端
那我掉的头发算什么2 小时前
【图书管理系统】基于Spring全家桶的图书管理系统(下)
java·数据库·spring boot·后端·spring·mybatis