Lettuce 指南 (Java)
提示
来自deepseek解释
原文链接:https://redis.io/docs/latest/develop/clients/lettuce/
代码示例图例
以下代码示例展示了如何使用不同的编程语言和客户端库执行相同的操作:
- Redis CLI:Redis 命令行界面
- C# (同步):StackExchange.Redis 同步客户端
- C# (异步):StackExchange.Redis 异步客户端
- Go:go-redis 客户端
- Java (同步 - Jedis):Jedis 同步客户端
- Java (异步 - Lettuce):Lettuce 异步客户端
- Java (响应式 - Lettuce):Lettuce 响应式/流式客户端
- JavaScript (Node.js):node-redis 客户端
- PHP:Predis 客户端
- Python:redis-py 客户端
- Rust (同步):redis-rs 同步客户端
- Rust (异步):redis-rs 异步客户端
每个代码示例都演示了跨不同语言的相同基本操作。具体的语法和模式因语言和客户端库而异,但底层的 Redis 命令和行为保持一致。
Lettuce 是一个用于 Redis 的高级 Java 客户端,支持同步、异步和响应式连接。如果您只需要同步连接,则可能会发现另一个 Java 客户端 Jedis 更易于使用。
以下部分说明如何安装 Lettuce 并将您的应用程序连接到 Redis 数据库。
Lettuce 需要正在运行的 Redis 服务器。请参阅此处了解 Redis 开源版本的安装说明。
安装
要在您的应用程序中将 Lettuce 作为依赖项引入,请按如下所示编辑相应的依赖文件。
如果您使用 Maven,请将以下依赖项添加到您的 pom.xml 中:
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.7.1.RELEASE</version> <!-- 请检查 Maven Central 上的最新版本 -->
</dependency>如果您使用 Gradle,请在 build.gradle 文件中包含此行:
dependencies {
compileOnly 'io.lettuce:lettuce-core:6.7.1.RELEASE'
}如果您希望直接使用 JAR 文件,请从 Maven Central 或任何其他 Maven 仓库下载最新的 Lettuce 以及可选的 Apache Commons Pool2 JAR 文件。
要从源码构建,请参阅 Lettuce 源码 GitHub 仓库上的说明。
连接与测试
使用以下代码连接到本地服务器。首先,导入所需的类。
基础:导入 Lettuce 所需的类以实现同步 Redis 连接
难度: 初级
可用语言: C, C#, C#, Go, Java, Java (同步 - Jedis), JavaScript (Node.js), JavaScript (Node.js), PHP, Python, Ruby, Rust (异步), Rust (同步)
C
// 以下注释为使示例交互式运行所需。
//%cflags:-lhiredis
#include <stdio.h>
#include <stdlib.h>
#include <hiredis/hiredis.h>
int main() {
// `redisContext` 类型表示与 Redis 服务器的连接。
// 此处,我们连接到默认主机和端口。
redisContext *c = redisConnect("127.0.0.1", 6379);
// 检查上下文是否为空或是否发生了特定错误。
if (c == NULL || c->err) {
if (c != NULL) {
printf("错误: %s\n", c->errstr);
// 处理错误
} else {
printf("无法分配 redis 上下文\n");
}
exit(1);
}
// 设置字符串键。
redisReply *reply = redisCommand(c, "SET foo bar");
printf("回复: %s\n", reply->str);
freeReplyObject(reply);
// 获取刚刚存储的键。
reply = redisCommand(c, "GET foo");
printf("回复: %s\n", reply->str);
freeReplyObject(reply);
// 关闭连接。
redisFree(c);
}C#
using StackExchange.Redis;Go
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)Java
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;Java (同步 - Jedis)
import redis.clients.jedis.RedisClient;
import java.util.HashMap;
import java.util.Map;JavaScript (Node.js)
import { createClient } from 'redis';
const client = createClient();
client.on('error', err => console.log('Redis Client Error', err));
await client.connect();
await client.set('key', 'value');
const value = await client.get('key');
console.log(value);
await client.hSet('user-session:123', {
name: 'John',
surname: 'Smith',
company: 'Redis',
age: 29
})
let userSession = await client.hGetAll('user-session:123');
console.log(JSON.stringify(userSession, null, 2));
await client.quit();JavaScript (Node.js)
import { Redis } from 'ioredis';
const redis = new Redis();
await redis.set('key', 'value');
const value = await redis.get('key');
console.log(value); // >>> value
await redis.hset('user-session:123', {
name: 'John',
surname: 'Smith',
company: 'Redis',
age: 29
});
const userSession = await redis.hgetall('user-session:123');
console.log(JSON.stringify(userSession, null, 2));
/* >>>
{
"surname": "Smith",
"name": "John",
"company": "Redis",
"age": "29"
}
*/
redis.disconnect();PHP
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
echo $r->set('foo', 'bar'), PHP_EOL;
// >>> OK
echo $r->get('foo'), PHP_EOL;
// >>> bar
$r->hset('user-session:123', 'name', 'John');
$r->hset('user-session:123', 'surname', 'Smith');
$r->hset('user-session:123', 'company', 'Redis');
$r->hset('user-session:123', 'age', 29);
echo var_export($r->hgetall('user-session:123')), PHP_EOL;
/* >>>
array (
'name' => 'John',
'surname' => 'Smith',
'company' => 'Redis',
'age' => '29',
)
*/Python
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.set('foo', 'bar')
# True
r.get('foo')
# bar
r.hset('user-session:123', mapping={
'name': 'John',
"surname": 'Smith',
"company": 'Redis',
"age": 29
})
# True
r.hgetall('user-session:123')
# {'surname': 'Smith', 'name': 'John', 'company': 'Redis', 'age': '29'}
r.close()Ruby
require 'redis'
r = Redis.new
r.set 'foo', 'bar'
value = r.get('foo')
puts value
r.hset 'user-session:123', 'name', 'John'
r.hset 'user-session:123', 'surname', 'Smith'
r.hset 'user-session:123', 'company', 'Redis'
r.hset 'user-session:123', 'age', 29
hash_value = r.hgetall('user-session:123')
puts hash_value
r.close()Rust (异步)
use redis::AsyncCommands;Rust (同步)
use redis::Commands;使用以下代码连接到服务器。
基础:使用 Lettuce 建立与 Redis 服务器的同步连接
难度: 初级
可用语言: C, C#, C#, Go, Java, Java (同步 - Jedis), JavaScript (Node.js), JavaScript (Node.js), PHP, Python, Ruby, Rust (异步), Rust (同步)
C
// 以下注释为使示例交互式运行所需。
//%cflags:-lhiredis
#include <stdio.h>
#include <stdlib.h>
#include <hiredis/hiredis.h>
int main() {
// `redisContext` 类型表示与 Redis 服务器的连接。
// 此处,我们连接到默认主机和端口。
redisContext *c = redisConnect("127.0.0.1", 6379);
// 检查上下文是否为空或是否发生了特定错误。
if (c == NULL || c->err) {
if (c != NULL) {
printf("错误: %s\n", c->errstr);
// 处理错误
} else {
printf("无法分配 redis 上下文\n");
}
exit(1);
}
// 设置字符串键。
redisReply *reply = redisCommand(c, "SET foo bar");
printf("回复: %s\n", reply->str);
freeReplyObject(reply);
// 获取刚刚存储的键。
reply = redisCommand(c, "GET foo");
printf("回复: %s\n", reply->str);
freeReplyObject(reply);
// 关闭连接。
redisFree(c);
}C#
var muxer = await ConnectionMultiplexer.ConnectAsync("localhost:6379");
var db = muxer.GetDatabase();C#
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();Go
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // 无密码
DB: 0, // 使用默认 DB
Protocol: 2,
})
ctx := context.Background()Java
RedisURI uri = RedisURI.Builder
.redis("localhost", 6379)
.build();
RedisClient client = RedisClient.create(uri);
StatefulRedisConnection<String, String> connection = client.connect();
RedisCommands<String, String> commands = connection.sync();Java (同步 - Jedis)
RedisClient jedis = new RedisClient("redis://localhost:6379");JavaScript (Node.js)
import { createClient } from 'redis';
const client = createClient();
client.on('error', err => console.log('Redis Client Error', err));
await client.connect();JavaScript (Node.js)
import { Redis } from 'ioredis';
const redis = new Redis();PHP
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);Python
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)Ruby
require 'redis'
r = Redis.newRust (异步)
let mut r = match redis::Client::open("redis://127.0.0.1") {
Ok(client) => {
match client.get_multiplexed_async_connection().await {
Ok(conn) => conn,
Err(e) => {
println!("连接到 Redis 失败: {e}");
return;
}
}
},
Err(e) => {
println!("创建 Redis 客户端失败: {e}");
return;
}
};Rust (同步)
let mut r = match redis::Client::open("redis://127.0.0.1") {
Ok(client) => {
match client.get_connection() {
Ok(conn) => conn,
Err(e) => {
println!("连接到 Redis 失败: {e}");
return;
}
}
},
Err(e) => {
println!("创建 Redis 客户端失败: {e}");
return;
}
};通过存储和检索一个简单的字符串来测试连接。
基础:使用 SET 和 GET 命令设置并获取字符串值以验证连接正常工作
难度: 初级
可用语言: C, C#, C#, Go, Java, Java (同步 - Jedis), JavaScript (Node.js), JavaScript (Node.js), PHP, Python, Ruby, Rust (异步), Rust (同步)
C
// 以下注释为使示例交互式运行所需。
//%cflags:-lhiredis
#include <stdio.h>
#include <stdlib.h>
#include <hiredis/hiredis.h>
int main() {
// `redisContext` 类型表示与 Redis 服务器的连接。
// 此处,我们连接到默认主机和端口。
redisContext *c = redisConnect("127.0.0.1", 6379);
// 检查上下文是否为空或是否发生了特定错误。
if (c == NULL || c->err) {
if (c != NULL) {
printf("错误: %s\n", c->errstr);
// 处理错误
} else {
printf("无法分配 redis 上下文\n");
}
exit(1);
}
// 设置字符串键。
redisReply *reply = redisCommand(c, "SET foo bar");
printf("回复: %s\n", reply->str);
freeReplyObject(reply);
// 获取刚刚存储的键。
reply = redisCommand(c, "GET foo");
printf("回复: %s\n", reply->str);
freeReplyObject(reply);
// 关闭连接。
redisFree(c);
}C#
await db.StringSetAsync("foo", "bar");
string? fooResult = await db.StringGetAsync("foo");
Console.WriteLine(fooResult); // >>> barC#
db.StringSet("foo", "bar");
Console.WriteLine(db.StringGet("foo")); // >>> barGo
err := rdb.Set(ctx, "foo", "bar", 0).Err()
if err != nil {
panic(err)
}
val, err := rdb.Get(ctx, "foo").Result()
if err != nil {
panic(err)
}
fmt.Println("foo", val) // >>> foo barJava
commands.set("foo", "bar");
String result = commands.get("foo");
System.out.println(result); // >>> barJava (同步 - Jedis)
String res1 = jedis.set("bike:1", "Deimos");
System.out.println(res1); // >>> OK
String res2 = jedis.get("bike:1");
System.out.println(res2); // >>> DeimosJavaScript (Node.js)
await client.set('key', 'value');
const value = await client.get('key');
console.log(value);JavaScript (Node.js)
await redis.set('key', 'value');
const value = await redis.get('key');
console.log(value); // >>> valuePHP
echo $r->set('foo', 'bar'), PHP_EOL;
// >>> OK
echo $r->get('foo'), PHP_EOL;
// >>> barPython
r.set('foo', 'bar')
# True
r.get('foo')
# barRuby
r.set 'foo', 'bar'
value = r.get('foo')
puts valueRust (异步)
if let Ok(res) = r.set("foo", "bar").await {
let res: String = res;
println!("{res}"); // >>> OK
} else {
println!("设置 foo 出错");
}
match r.get("foo").await {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> bar
},
Err(e) => {
println!("获取 foo 出错: {e}");
return;
}
};Rust (同步)
if let Ok(res) = r.set("foo", "bar") {
let res: String = res;
println!("{res}"); // >>> OK
} else {
println!("设置 foo 出错");
}
match r.get("foo") {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> bar
},
Err(e) => {
println!("获取 foo 出错: {e}");
return;
}
};完成后关闭连接。
基础:正确关闭 Lettuce 连接以释放资源
难度: 初级
可用语言: C, C#, C#, Go, Java, Java (同步 - Jedis), JavaScript (Node.js), JavaScript (Node.js), PHP, Python, Ruby, Rust (异步), Rust (同步)
C
// 以下注释为使示例交互式运行所需。
//%cflags:-lhiredis
#include <stdio.h>
#include <stdlib.h>
#include <hiredis/hiredis.h>
int main() {
// `redisContext` 类型表示与 Redis 服务器的连接。
// 此处,我们连接到默认主机和端口。
redisContext *c = redisConnect("127.0.0.1", 6379);
// 检查上下文是否为空或是否发生了特定错误。
if (c == NULL || c->err) {
if (c != NULL) {
printf("错误: %s\n", c->errstr);
// 处理错误
} else {
printf("无法分配 redis 上下文\n");
}
exit(1);
}
// 设置字符串键。
redisReply *reply = redisCommand(c, "SET foo bar");
printf("回复: %s\n", reply->str);
freeReplyObject(reply);
// 获取刚刚存储的键。
reply = redisCommand(c, "GET foo");
printf("回复: %s\n", reply->str);
freeReplyObject(reply);
// 关闭连接。
redisFree(c);
}C#
using StackExchange.Redis;
public class AsyncLandingExample
{
public async Task Run()
{
var muxer = await ConnectionMultiplexer.ConnectAsync("localhost:6379");
var db = muxer.GetDatabase();
await db.StringSetAsync("foo", "bar");
string? fooResult = await db.StringGetAsync("foo");
Console.WriteLine(fooResult); // >>> bar
var hash = new HashEntry[] {
new HashEntry("name", "John"),
new HashEntry("surname", "Smith"),
new HashEntry("company", "Redis"),
new HashEntry("age", "29"),
};
await db.HashSetAsync("user-session:123", hash);
var hashFields = await db.HashGetAllAsync("user-session:123");
Console.WriteLine(String.Join("; ", hashFields));
// >>> name: John; surname: Smith; company: Redis; age: 29
}
}C#
using StackExchange.Redis;
public class SyncLandingExample
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
db.StringSet("foo", "bar");
Console.WriteLine(db.StringGet("foo")); // >>> bar
var hash = new HashEntry[] {
new HashEntry("name", "John"),
new HashEntry("surname", "Smith"),
new HashEntry("company", "Redis"),
new HashEntry("age", "29"),
};
db.HashSet("user-session:123", hash);
var hashFields = db.HashGetAll("user-session:123");
Console.WriteLine(String.Join("; ", hashFields));
// >>> name: John; surname: Smith; company: Redis; age: 29
}
}Go
rdb.Close()Java
connection.close();
client.shutdown();Java (同步 - Jedis)
jedis.close();JavaScript (Node.js)
await client.quit();JavaScript (Node.js)
redis.disconnect();PHP
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
echo $r->set('foo', 'bar'), PHP_EOL;
// >>> OK
echo $r->get('foo'), PHP_EOL;
// >>> bar
$r->hset('user-session:123', 'name', 'John');
$r->hset('user-session:123', 'surname', 'Smith');
$r->hset('user-session:123', 'company', 'Redis');
$r->hset('user-session:123', 'age', 29);
echo var_export($r->hgetall('user-session:123')), PHP_EOL;
/* >>>
array (
'name' => 'John',
'surname' => 'Smith',
'company' => 'Redis',
'age' => '29',
)
*/Python
r.close()Ruby
r.close()Rust (异步)
mod tests {
use redis::AsyncCommands;
async fn run() {
let mut r = match redis::Client::open("redis://127.0.0.1") {
Ok(client) => {
match client.get_multiplexed_async_connection().await {
Ok(conn) => conn,
Err(e) => {
println!("连接到 Redis 失败: {e}");
return;
}
}
},
Err(e) => {
println!("创建 Redis 客户端失败: {e}");
return;
}
};
if let Ok(res) = r.set("foo", "bar").await {
let res: String = res;
println!("{res}"); // >>> OK
} else {
println!("设置 foo 出错");
}
match r.get("foo").await {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> bar
},
Err(e) => {
println!("获取 foo 出错: {e}");
return;
}
};
let hash_fields = [
("model", "Deimos"),
("brand", "Ergonom"),
("type", "Enduro bikes"),
("price", "4972"),
];
if let Ok(res) = r.hset_multiple("bike:1", &hash_fields).await {
let res: String = res;
println!("{res}"); // >>> OK
} else {
println!("设置 bike:1 出错");
}
match r.hget("bike:1", "model").await {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> Deimos
},
Err(e) => {
println!("获取 bike:1 model 出错: {e}");
return;
}
}
match r.hget("bike:1", "price").await {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> 4972
},
Err(e) => {
println!("获取 bike:1 price 出错: {e}");
return;
}
}
match r.hgetall("bike:1").await {
Ok(res) => {
let res: Vec<(String, String)> = res;
for (key, value) in res {
println!("{key}: {value}");
}
// >>> model: Deimos
// >>> brand: Ergonom
// >>> type: Enduro bikes
// >>> price: 4972
},
Err(e) => {
println!("获取 bike:1 出错: {e}");
return;
}
}
}
}Rust (同步)
mod landing_tests {
use redis::Commands;
fn run() {
let mut r = match redis::Client::open("redis://127.0.0.1") {
Ok(client) => {
match client.get_connection() {
Ok(conn) => conn,
Err(e) => {
println!("连接到 Redis 失败: {e}");
return;
}
}
},
Err(e) => {
println!("创建 Redis 客户端失败: {e}");
return;
}
};
if let Ok(res) = r.set("foo", "bar") {
let res: String = res;
println!("{res}"); // >>> OK
} else {
println!("设置 foo 出错");
}
match r.get("foo") {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> bar
},
Err(e) => {
println!("获取 foo 出错: {e}");
return;
}
};
let hash_fields = [
("model", "Deimos"),
("brand", "Ergonom"),
("type", "Enduro bikes"),
("price", "4972"),
];
if let Ok(res) = r.hset_multiple("bike:1", &hash_fields) {
let res: String = res;
println!("{res}"); // >>> OK
} else {
println!("设置 bike:1 出错");
}
match r.hget("bike:1", "model") {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> Deimos
},
Err(e) => {
println!("获取 bike:1 model 出错: {e}");
return;
}
}
match r.hget("bike:1", "price") {
Ok(res) => {
let res: String = res;
println!("{res}"); // >>> 4972
},
Err(e) => {
println!("获取 bike:1 price 出错: {e}");
return;
}
}
match r.hgetall("bike:1") {
Ok(res) => {
let res: Vec<(String, String)> = res;
for (key, value) in res {
println!("{key}: {value}");
}
// >>> model: Deimos
// >>> brand: Ergonom
// >>> type: Enduro bikes
// >>> price: 4972
},
Err(e) => {
println!("获取 bike:1 出错: {e}");
return;
}
}
}
}更多信息
Lettuce 参考指南 提供了更多示例和 API 参考。您可能还对 Lettuce 使用的 Project Reactor 库感兴趣。
请参阅本部分中的其他页面以获取更多信息和示例。