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 容器中注册一个名为 redisTemplate 的 RedisTemplate 实例,然后将自动注入的 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清除缓存,确保数据的一致性。