引言
在开发过程中,缓存是提高应用性能的关键技术之一。Redis 是一个高性能的键值存储系统,常用于缓存、消息队列和数据存储。本文将详细介绍如何在 SpringBoot 项目中整合 Redis,包括配置、基本操作和一些最佳实践。
1.环境准备
首先,确保你的开发环境中已经安装了 Redis,并且 Redis 服务已经启动。如果你没有安装 Redis,可以访问Redis 官网下载并安装。
启动命令:
Linux系统:
sudo systemctl start redis
Windows系统:
先进入redis的安装目录下
cd C:\redis
打开cmd,输入:
redis-server.exe redis.windows.conf
2.添加依赖
创建一个 SpringBoot 项目,并添加 Redis 相关的依赖
在 pom.xml 中添加 Redis 相关的依赖:
<dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Starter Data Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Spring Boot Starter Cache --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!-- Lettuce (用于 Redis 的客户端) --><dependency><groupId>io.lettuce.core</groupId><artifactId>lettuce-core</artifactId></dependency><!-- Spring Boot Starter Logging (可选,调试用) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency>
</dependencies>
说明:
- spring-boot-starter-data-redis: 提供了 Spring Data Redis 支持。
- spring-boot-starter-cache: 提供了 Spring 缓存抽象,支持多种缓存实现(包括 Redis)。
- lettuce-core: Redis 客户端,Spring Boot 默认使用 Lettuce 客户端来连接 Redis。
3. 配置 Redis
在 application.properties 或 application.yml 中配置 Redis 连接信息:
application.properties 配置:
# Redis 服务器地址
spring.redis.host=localhost
# Redis 端口
spring.redis.port=6379
# Redis 数据库索引,默认为 0
spring.redis.database=0
# Redis 密码,默认没有密码
spring.redis.password=your_password
# 使用 Lettuce 客户端
spring.redis.client-type=lettuce
application.yml配置:
spring:redis:host: localhostport: 6379password: your_passworddatabase: 0
说明:
- host: Redis 服务器地址
- port: Redis 端口
- password:Redis 密码,默认没有密码
- database: Redis 数据库索引,默认为 0
4. 开启缓存支持
在 SpringBoot 中启用缓存非常简单,只需要在启动类上添加 @EnableCaching 注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication
@EnableCaching // 开启缓存支持
public class RedisApplication {public static void main(String[] args) {SpringApplication.run(RedisApplication.class, args);}
}
5. 配置 RedisTemplate
RedisTemplate 是 Spring Data Redis 提供的操作 Redis 的工具类。通过 RedisTemplate,你可以执行各种 Redis 操作(如字符串、哈希、列表等)。下面是一个简单的配置。
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {// 配置 RedisTemplate@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);// 设置 key 的序列化方式template.setKeySerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer());// 设置 value 的序列化方式template.setValueSerializer(new GenericJackson2JsonRedisSerializer());template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());return redisTemplate;}
}
- setKeySerializer(new StringRedisSerializer()): 设置 Redis 的 key 序列化方式为字符串。
- setValueSerializer(new StringRedisSerializer()): 设置 Redis 的 value 序列化方式为字符串。
注意:如果没有配置序列化方式的话,打开Redis图形化工具会发现刚才存入的数据变成了一堆乱码。
这是因为Redis的序列化并没有按照我们预期的进行转化,所以需要自己去重写一个序列化,如上配置就是将key设置为String类型、value设置为Json类型,最后将这个对象交给Spring管理,之后在调用该对象的时候就会自动选择我们配置的这个。
6.RedisTemplate 使用
RedisTemplate 提供了丰富的方法来实现对 Redis 的各种操作,包括但不限于字符串、哈希、列表、集合和有序集合等数据结构的操作。以下是一些常用的 RedisTemplate API:
6.1 字符串操作
- opsForValue().set(key, value): 设置字符串值。
// 设置键 "username" 的值为 "john_doe"
redisTemplate.opsForValue().set("username", "john_doe");
- opsForValue().get(key): 获取字符串值。
String username = redisTemplate.opsForValue().get("username"); // 获取 "username" 的值
System.out.println(username); // 输出 "john_doe"
- opsForValue().incr(key): 字符串值自增。
redisTemplate.opsForValue().set("counter", "10"); // 设置初始值为 10
Long newCounterValue = redisTemplate.opsForValue().increment("counter"); // 将 "counter" 的值加 1,新的值为 11
System.out.println(newCounterValue); // 输出 11
- opsForValue().decr(key): 字符串值自减。
redisTemplate.opsForValue().set("counter", "10"); // 设置初始值为 10
Long newCounterValue = redisTemplate.opsForValue().decrement("counter"); // 将 "counter" 的值减 1,新的值为 9
System.out.println(newCounterValue); // 输出 9
6.2 哈希操作
- opsForHash().getOperations().put(key, hashKey, value): 向哈希中添加键值对。
redisTemplate.opsForHash().put("user:1001", "name", "John Doe"); // 向哈希 "user:1001" 中添加 "name": "John Doe"
- opsForHash().getOperations().get(key, hashKey): 获取哈希中的值。
String name = redisTemplate.opsForHash().get("user:1001", "name"); // 获取哈希 "user:1001" 中 "name" 字段的值
System.out.println(name); // 输出 "John Doe"
- opsForHash().getOperations().entries(key): 获取哈希中的所有键值对。
Map<String, String> userDetails = redisTemplate.opsForHash().entries("user:1001"); // 获取 "user:1001" 哈希中的所有键值对
6.3 列表操作
- opsForList().leftPush(key, value): 从列表左侧添加元素。
redisTemplate.opsForList().leftPush("myList", "item1"); // 将 "item1" 添加到列表 "myList" 左侧
- opsForList().rightPush(key, value): 从列表右侧添加元素。
redisTemplate.opsForList().rightPush("myList", "item2"); // 将 "item2" 添加到列表 "myList" 右侧
- opsForList().leftPop(key): 从列表左侧弹出元素。
String leftItem = redisTemplate.opsForList().leftPop("myList"); // 从列表 "myList" 左侧弹出元素
System.out.println(leftItem); // 输出 "item1"
- opsForList().rightPop(key): 从列表右侧弹出元素。
String rightItem = redisTemplate.opsForList().rightPop("myList"); // 从列表 "myList" 右侧弹出元素
System.out.println(rightItem); // 输出 "item2"
6.4 集合操作
- opsForSet().add(key, value): 向集合中添加元素。
redisTemplate.opsForSet().add("mySet", "value1", "value2", "value3"); // 向集合 "mySet" 中添加 "value1", "value2", "value3"
- opsForSet().members(key): 获取集合中的所有元素。
Set<String> members = redisTemplate.opsForSet().members("mySet"); // 获取集合 "mySet" 中的所有元素
System.out.println(members); // 输出 [value1, value2, value3]
- opsForSet().remove(key, value): 从集合中移除元素。
redisTemplate.opsForSet().remove("mySet", "value2"); // 从集合 "mySet" 中移除 "value2"
6.5 有序集合操作
- opsForZSet().add(key, value, score): 向有序集合中添加元素,并指定分数。
redisTemplate.opsForZSet().add("myZSet", "item1", 1.0); // 向有序集合 "myZSet" 添加元素 "item1" 并指定分数 1.0
redisTemplate.opsForZSet().add("myZSet", "item2", 2.0); // 向有序集合 "myZSet" 添加元素 "item2" 并指定分数 2.0
- opsForZSet().range(key, start, end): 获取有序集合中指定分数范围内的元素。
Set<String> rangeItems = redisTemplate.opsForZSet().range("myZSet", 0, -1); // 获取 "myZSet" 有序集合中所有元素,按分数升序排列
System.out.println(rangeItems); // 输出 [item1, item2]
- opsForZSet().removeRangeByScore(key, minScore, maxScore): 按分数范围移除有序集合中的元素。
redisTemplate.opsForZSet().removeRangeByScore("myZSet", 1.0, 1.5); // 移除 "myZSet" 中分数在 [1.0, 1.5] 范围内的元素
6.6 键操作
- delete(key): 删除键。
redisTemplate.delete("myKey"); // 删除键 "myKey"
- hasKey(key): 检查键是否存在。
boolean exists = redisTemplate.hasKey("myKey"); // 检查键 "myKey" 是否存在
System.out.println(exists); // 输出 true 或 false
- keys(pattern): 根据模式匹配获取所有键。
Set<String> keys = redisTemplate.keys("user:*"); // 获取所有以 "user:" 开头的键
System.out.println(keys); // 输出 {user:1001, user:1002, user:1003}
更多操作可以查看官方提供的API文档:RedisTemplate (Spring Data Redis 3.3.2 API)