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

相关推荐
曹牧23 分钟前
文档格式:OFD
java
豆角焖肉1 小时前
Maven进阶与搭建私服
java·maven
大不点wow1 小时前
Java序列化与反序列化:让对象走出JVM
java·开发语言·jvm
止语Lab1 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活1 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
噢,我明白了1 小时前
Java中日期和字符串的处理
java·开发语言·日期
程序员天天困1 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn1 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
dkbnull1 小时前
Spring Boot请求处理组件对比详解
java·spring boot
jun_bai1 小时前
Orthanc服务器使用java上传dicom影像文件
java·运维·服务器