目录
- 环境准备
- 核心依赖
- 建立连接
- 核心 API: 获取各种类型的数据
- 字符串
- 哈希
- 列表
- 集合
- 有序集合
- 连接池
- 最佳实践
- 完整示例代码
环境准备
在开始之前,请确保你已经:

- 安装并运行了 Redis 服务器。
- 有一个 Java 开发环境。
你可以使用 redis-cli 连接到你的 Redis 服务器,并设置一些测试数据,方便后续 Java 代码调用:
# 连接到 Redis redis-cli # 设置一些测试数据 > SET java_key "Hello, Redis!" > OK > HSET java_hash user:1 name "Alice" age 30 > (integer) 2 > LPUSH java_list "Item 3" > (integer) 1 > LPUSH java_list "Item 2" > (integer) 2 > LPUSH java_list "Item 1" > (integer) 3 > SADD java_set "apple" "banana" "orange" > (integer) 3 > ZADD java_zset 1 "one" 2 "two" 3 "three" > (integer) 3 # 退出 > exit
核心依赖
在 Java 中,最流行和功能最全的 Redis 客户端是 Lettuce 和 Jedis。Spring Boot 项目通常默认使用 Lettuce,因为它基于 Netty,是异步和非阻塞的,性能更好。
这里我们以 Lettuce 为例。
如果你使用 Maven,在 pom.xml 中添加依赖:

<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.2.6.RELEASE</version> <!-- 使用较新的稳定版本 -->
</dependency>
如果你使用 Gradle,在 build.gradle 中添加:
implementation 'io.lettuce:lettuce-core:6.2.6.RELEASE' // 使用较新的稳定版本
建立连接
你需要创建一个 RedisClient 实例并建立连接。
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
public class RedisConnectionExample {
public static void main(String[] args) {
// 1. 创建 RedisURI,指定 Redis 服务器的地址和端口
RedisURI redisURI = RedisURI.create("redis://localhost:6379");
// 2. 创建 RedisClient
RedisClient redisClient = RedisClient.create(redisURI);
// 3. 创建一个同步连接 (StatefulRedisConnection)
// 同步 API 会阻塞当前线程,直到操作完成。
StatefulRedisConnection<String, String> connection = redisClient.connect();
// 4. 获取 RedisCommands 接口,用于执行命令
RedisCommands<String, String> syncCommands = connection.sync();
// ... 在这里执行你的 Redis 操作 ...
// 5. 操作完成后,关闭连接
connection.close();
redisClient.shutdown();
}
}
核心 API: 获取各种类型的数据
RedisCommands 接口提供了与 Redis 命令一一对应的方法,方法名通常是命令的小写形式。
a. 获取字符串
Redis 的 GET 命令对应 syncCommands.get(key)。

// 获取之前设置的 "java_key"
String value = syncCommands.get("java_key");
System.out.println("获取到的字符串值: " + value); // 输出: Hello, Redis!
// key 不存在,get() 方法会返回 null
String nonExistentValue = syncCommands.get("non_existent_key");
System.out.println("不存在的 key 的值: " + nonExistentValue); // 输出: null
b. 获取哈希
哈希表的操作比较丰富,如 hget, hgetall, hvals 等。
// 获取哈希表中某个 field 的值
String name = syncCommands.hget("java_hash", "user:1:name");
System.out.println("获取到的 name: " + name); // 输出: Alice
// 获取哈希表中的所有 field-value 对
Map<String, String> allFields = syncCommands.hgetall("java_hash");
System.out.println("获取到的所有哈希字段: " + allFields);
// 输出: {user:1:age=30, user:1:name=Alice}
// 获取哈希表中的所有 value
List<String> allValues = syncCommands.hvals("java_hash");
System.out.println("获取到的所有哈希值: " + allValues);
// 输出: [30, Alice]
c. 获取列表
列表的获取方法包括 lindex (获取指定索引元素), lrange (获取一个范围的元素)。
// 获取列表中指定索引的元素 (0-based)
// "Item 1" 在索引 0
String firstItem = syncCommands.lindex("java_list", 0);
System.out.println("获取到的第一个元素: " + firstItem); // 输出: Item 1
// 获取列表中指定范围内的元素
// LRANGE java_list 0 -1 表示获取整个列表
List<String> allItems = syncCommands.lrange("java_list", 0, -1);
System.out.println("获取到的所有列表元素: " + allItems);
// 输出: [Item 1, Item 2, Item 3]
d. 获取集合
集合是无序的,所以通常使用 smembers 获取所有成员。
// 获取集合中的所有成员
Set<String> members = syncCommands.smembers("java_set");
System.out.println("获取到的集合成员: " + members);
// 输出: [orange, apple, banana] (顺序可能不同)
e. 获取有序集合
有序集合的获取方法包括 zrange (按分数排序获取成员), zrevrange (按分数倒序获取), zrangeWithScores (获取成员和分数)。
// 按分数从低到高获取成员 (默认是升序)
Set<String> zSetMembers = syncCommands.zrange("java_zset", 0, -1);
System.out.println("获取到的有序集合成员(升序): " + zSetMembers);
// 输出: [one, two, three]
// 获取成员及其对应的分数
List<Tuple<String, Double>> zSetWithScores = syncCommands.zrangeWithScores("java_zset", 0, -1);
System.out.println("获取到的有序集合成员和分数: " + zSetWithScores);
// 输出: [one:1.0, two:2.0, three:3.0]
连接池
在高并发场景下,频繁地创建和销毁连接是非常消耗资源的,使用连接池是必须的。
Lettuce 提供了 LettuceConnectionFactory 和 RedisTemplate (通常与 Spring Data Redis 一起使用) 来简化连接池管理,但如果你不想用 Spring,也可以直接使用 GenericObjectPool。
这里展示一个简化的连接池用法(实际项目中建议使用 Spring Data Redis 或更成熟的池化库):
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
// ... (省略 RedisClient 的创建)
// 创建连接池配置
GenericObjectPoolConfig<StatefulRedisConnection<String, String>> poolConfig = new GenericObjectPoolConfig<>();
poolConfig.setMaxTotal(20); // 最大连接数
poolConfig.setMaxIdle(10); // 最大空闲连接数
// 创建连接池
GenericObjectPool<StatefulRedisConnection<String, String>> connectionPool = new GenericObjectPool<>(new BasePooledObjectFactory<StatefulRedisConnection<String, String>>() {
@Override
public StatefulRedisConnection<String, String> create() throws Exception {
return redisClient.connect();
}
}, poolConfig);
// 从连接池中获取连接
try (StatefulRedisConnection<String, String> connection = connectionPool.borrowObject()) {
RedisCommands<String, String> commands = connection.sync();
String value = commands.get("java_key");
System.out.println("从连接池获取数据: " + value);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 将连接返回到池中 (try-with-resources 会自动处理)
// connectionPool.returnObject(connection);
}
// 关闭连接池
connectionPool.close();
redisClient.shutdown();
强烈推荐: 在 Spring Boot 项目中,直接使用 Spring Data Redis,它会自动为你配置好基于 Lettuce 的连接池,你只需要注入 RedisTemplate 或 StringRedisTemplate 即可,非常方便。
最佳实践
- 使用连接池:如上所述,避免频繁创建销毁连接。
- 异常处理:Redis 操作可能会因为网络问题、服务宕机等而失败,务必使用
try-catch块来捕获RedisException或其他可能的异常。 - 资源释放:确保
StatefulRedisConnection在使用后被正确关闭,推荐使用try-with-resources语句,它可以自动关闭实现了AutoCloseable接口的资源。 - 选择合适的 API:
- 同步 API (
RedisCommands):简单直观,适用于大多数场景,但会阻塞调用线程。 - 异步 API (
RedisAsyncCommands):返回RedisFuture,适用于高并发、非阻塞的场景,性能更高。 - 响应式 API (
RedisReactiveCommands):返回Mono或Flux,可以与 Project Reactor 或 RxJava 等响应式框架无缝集成,构建高性能、非阻塞的应用。
- 同步 API (
- 使用序列化/反序列化工具:当你存储 Java 对象时,需要将其序列化为字节,Spring Data Redis 提供了多种
Serializer实现,如GenericJackson2JsonRedisSerializer(推荐,可读性好且支持泛型) 和JdkSerializationRedisSerializer。
完整示例代码
这是一个整合了上述所有点的完整示例。
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class RedisDataFetcher {
public static void main(String[] args) {
// 1. 配置和创建连接
RedisURI redisURI = RedisURI.create("redis://localhost:6379");
RedisClient redisClient = RedisClient.create(redisURI);
// 使用 try-with-resources 确保连接被关闭
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisCommands<String, String> syncCommands = connection.sync();
System.out.println("--- 获取字符串数据 ---");
fetchStringData(syncCommands);
System.out.println("\n--- 获取哈希数据 ---");
fetchHashData(syncCommands);
System.out.println("\n--- 获取列表数据 ---");
fetchListData(syncCommands);
System.out.println("\n--- 获取集合数据 ---");
fetchSetData(syncCommands);
System.out.println("\n--- 获取有序集合数据 ---");
fetchZSetData(syncCommands);
} catch (Exception e) {
System.err.println("操作 Redis 时发生错误: " + e.getMessage());
e.printStackTrace();
} finally {
// 2. 关闭客户端
redisClient.shutdown();
}
}
private static void fetchStringData(RedisCommands<String, String> commands) {
String key = "java_key";
String value = commands.get(key);
if (value != null) {
System.out.println("Key: " + key + ", Value: " + value);
} else {
System.out.println("Key: " + key + " 不存在。");
}
}
private static void fetchHashData(RedisCommands<String, String> commands) {
String key = "java_hash";
Map<String, String> hashData = commands.hgetall(key);
System.out.println("Key: " + key + ", All Fields and Values: " + hashData);
}
private static void fetchListData(RedisCommands<String, String> commands) {
String key = "java_list";
// 获取列表的全部元素
List<String> listData = commands.lrange(key, 0, -1);
System.out.println("Key: " + key + ", All Items: " + listData);
}
private static void fetchSetData(RedisCommands<String, String> commands) {
String key = "java_set";
Set<String> setData = commands.smembers(key);
System.out.println("Key: " + key + ", All Members: " + setData);
}
private static void fetchZSetData(RedisCommands<String, String> commands) {
String key = "java_zset";
// 获取有序集合的全部成员(按分数升序)
Set<String> zSetData = commands.zrange(key, 0, -1);
System.out.println("Key: " + key + ", All Members (ordered by score): " + zSetData);
}
}
运行这个代码,你应该能看到从你的 Redis 实例中获取的所有测试数据。
