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清除缓存,确保数据的一致性。

相关推荐
程序员夏洛1 分钟前
Spring Boot 多模块项目中 IDEA 提示 Cannot resolve symbol 的一次排查记录
后端
子兮曰5 分钟前
OpenMontage 深度解剖:你的 AI 编程助手,其实是个视频工作室
前端·后端·ai编程
子兮曰12 分钟前
前端工具链的「Rust 化」:一场没有赢家的军备竞赛?
前端·后端·rust
爱勇宝1 小时前
从 Ctrl+CV 到 Enter:程序员正在失去什么
前端·后端·程序员
码事漫谈2 小时前
EdgeOne Makers + WorkBuddy:零基础也能快速搭建可上线的 AI 智能体(附图文教程)
后端
像我这样帅的人丶你还2 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩2 小时前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构
烤代码的吐司君3 小时前
Redis 数据结构 ZSet, BIT, HyperLogLog,Geo 空间数据
redis·后端
苏三说技术3 小时前
为什么越来越多的人使用FastAPI?
后端
JavaGuide3 小时前
比 iTerm2 更适合 Claude Code/Codex 的终端,我换成 Ghostty 了
人工智能·后端