杰瑞科技汇

Java中如何使用Redis API?

Of course! Here is a comprehensive guide to using Redis with Java, covering the most popular clients, basic operations, and advanced features.

Java中如何使用Redis API?-图1
(图片来源网络,侵删)

Choosing a Java Redis Client

There are two main, officially recommended clients for Java:

  1. Jedis: A simple, mature, and straightforward client. It's a direct, thread-unsafe wrapper around the Redis protocol. You need to manage connections yourself, often using a connection pool (like JedisPool).
  2. Lettuce: A modern, advanced, and thread-safe client built on Netty. It supports synchronous, asynchronous, and reactive programming models. It manages its own I/O and is generally considered the go-to choice for new applications.

Recommendation: For most new projects, Lettuce is the recommended choice due to its modern architecture and feature set. However, Jedis is still perfectly fine, especially for simpler use cases.


Setup with Lettuce (Recommended)

Step 1: Add Dependency

Add the Lettuce dependency to your pom.xml (Maven) or build.gradle (Gradle).

Maven (pom.xml):

Java中如何使用Redis API?-图2
(图片来源网络,侵删)
<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.3.2.RELEASE</version> <!-- Use the latest version -->
</dependency>

Gradle (build.gradle):

implementation 'io.lettuce:lettuce-core:6.3.2.RELEASE' // Use the latest version

Step 2: Create a Redis Connection

Lettuce uses a RedisClient to manage connections. It's best practice to create a single RedisClient instance and share it across your application.

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 RedisExample {
    public static void main(String[] args) {
        // 1. Create a Redis URI
        RedisURI redisUri = RedisURI.create("redis://localhost:6379");
        // 2. Create a Redis Client
        RedisClient redisClient = RedisClient.create(redisUri);
        // 3. Create a connection (StatefulRedisConnection is thread-safe and can be shared)
        // Use try-with-resources to ensure the connection is closed
        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            // 4. Get a synchronous API for executing commands
            RedisCommands<String, String> syncCommands = connection.sync();
            // Now you can use syncCommands to interact with Redis
            System.out.println("Connected to Redis successfully!");
            // Basic operations will be demonstrated below
            syncCommands.set("user:1001:name", "Alice");
            String name = syncCommands.get("user:1001:name");
            System.out.println("Name: " + name);
        } finally {
            // 5. Shutdown the client to release resources
            redisClient.shutdown();
        }
    }
}

Common Redis Operations with Lettuce

Let's explore the most common data structures.

Basic String Operations

// Assuming 'syncCommands' is a RedisCommands<String, String> instance
// SET a key-value pair
syncCommands.set("message", "Hello, Redis!");
// GET a value
String message = syncCommands.get("message");
System.out.println("Message: " + message); // Output: Message: Hello, Redis!
// SET with an expiration (TTL - Time To Live)
syncCommands.setex("temp_session", 60, "session_data_123");
// INCR (increment)
syncCommands.set("counter", "10");
syncCommands.incr("counter"); // Now it's 11
long counter = syncCommands.get("counter");
System.out.println("Counter: " + counter); // Output: Counter: 11

Hash Operations

// HSET (set a hash field)
syncCommands.hset("user:1001", "name", "Bob");
syncCommands.hset("user:1001", "email", "bob@example.com");
// HGET (get a hash field)
String email = syncCommands.hget("user:1001", "email");
System.out.println("Email: " + email); // Output: Email: bob@example.com
// HGETALL (get all fields and values)
Map<String, String> user = syncCommands.hgetall("user:1001");
System.out.println("User: " + user); // Output: User: {name=Bob, email=bob@example.com}
// HINCRBY (increment a hash field value)
syncCommands.hset("user:1001:stats", "login_count", "5");
syncCommands.hincrby("user:1001:stats", "login_count", 1);
int logins = Integer.parseInt(syncCommands.hget("user:1001:stats", "login_count"));
System.out.println("Logins: " + logins); // Output: Logins: 6

List Operations

// LPUSH (add to the head of the list)
syncCommands.lpush("notifications", "New follower", "New like");
// LRANGE (get a range of elements)
// 0 to -1 means get all elements
List<String> notifications = syncCommands.lrange("notifications", 0, -1);
System.out.println("Notifications: " + notifications); // Output: [New like, New follower]
// LPOP (remove and get the first element)
String firstNotification = syncCommands.lpop("notifications");
System.out.println("Popped: " + firstNotification); // Output: Popped: New like

Set Operations

// SADD (add members to a set)
syncCommands.sadd("tags:java", "programming", "backend", "jvm");
// SMEMBERS (get all members of a set)
Set<String> javaTags = syncCommands.smembers("tags:java");
System.out.println("Java Tags: " + javaTags); // Output: [jvm, programming, backend] (order not guaranteed)
// SISMEMBER (check if a member exists)
boolean hasTag = syncCommands.sismember("tags:java", "web");
System.out.println("Has 'web' tag? " + hasTag); // Output: Has 'web' tag? false

Sorted Set (ZSET) Operations

// ZADD (add members with a score to a sorted set)
syncCommands.zadd("leaderboard", 150, "player1");
syncCommands.zadd("leaderboard", 200, "player2");
syncCommands.zadd("leaderboard", 100, "player3");
// ZRANGE (get members in a range by score, from low to high)
// 0 to -1 means get all members, ordered by score
Set<String> allPlayers = syncCommands.zrange("leaderboard", 0, -1);
System.out.println("Leaderboard (low to high): " + allPlayers); // Output: [player3, player1, player2]
// ZREVRANGE (get members in a range by score, from high to low)
Set<String> topPlayers = syncCommands.zrevrange("leaderboard", 0, -1);
System.out.println("Leaderboard (high to low): " + topPlayers); // Output: [player2, player1, player3]

Advanced Features with Lettuce

Pipelining for Performance

Pipelining sends multiple commands to the server without waiting for a response for each one, which can significantly reduce network latency.

Java中如何使用Redis API?-图3
(图片来源网络,侵删)
// Lettuce makes this very easy
List<Object> results = syncCommands.multi() // Start a pipeline
    .set("key1", "value1")
    .get("key1")
    .set("key2", "value2")
    .get("key2")
    .exec(); // Execute all commands and get results
System.out.println(results); // Output: [OK, value1, OK, value2]

Transactions

Redis transactions ensure that a group of commands are executed atomically. The MULTI/EXEC block in the pipeline example above is a transaction.

Pub/Sub (Publish/Subscribe)

This is an advanced pattern for messaging. The API is slightly different as it's event-driven.

import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
import io.lettuce.core.pubsub.RedisPubSubListener;
// 1. Create a Pub/Sub connection
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisPubSubConnection<String, String> pubsubConn = redisClient.connectPubSub()) {
    // 2. Define a listener
    RedisPubSubListener<String, String> listener = new RedisPubSubListener<>() {
        @Override
        public void message(String channel, String message) {
            System.out.println("Message received on channel '" + channel + "': " + message);
        }
        @Override
        public void unsubscribed(String channel, long count) {
            System.out.println("Unsubscribed from channel: " + channel);
        }
        @Override
        public void subscribed(String channel, long count) {
            System.out.println("Subscribed to channel: " + channel);
        }
        @Override
        public void message(String pattern, String channel, String message) {
            System.out.println("Message received on pattern '" + pattern + "' for channel '" + channel + "': " + message);
        }
    };
    // 3. Add the listener and subscribe to a channel
    pubsubConn.addListener(listener);
    pubsubConn.sync().subscribe("news");
    System.out.println("Subscribed to 'news' channel. Waiting for messages...");
    // In a real application, you would run this in a separate thread
    // or use an event loop. Here, we'll just wait for a bit.
    Thread.sleep(10000); 
    // 4. Publish a message (this would be done from another part of your app)
    // pubsubConn.sync().publish("news", "Java is awesome!");
} finally {
    redisClient.shutdown();
}

Setup with Jedis (The Classic Alternative)

If you prefer or need to use Jedis, the setup is very similar.

Step 1: Add Dependency

Maven (pom.xml):

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>5.1.0</version> <!-- Use the latest version -->
</dependency>

Step 2: Use a Connection Pool

Jedis is not thread-safe, so you must use a JedisPool to manage connections.

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisExample {
    public static void main(String[] args) {
        // Configure the pool
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(10);
        poolConfig.setMaxIdle(5);
        // Create a connection pool
        try (JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379)) {
            // Get a connection from the pool
            try (Jedis jedis = jedisPool.getResource()) {
                System.out.println("Connected to Redis with Jedis!");
                // Basic operations
                jedis.set("jedis:message", "Hello from Jedis!");
                String msg = jedis.get("jedis:message");
                System.out.println("Message: " + msg);
                // Hash operations
                jedis.hset("jedis:user:1002", "name", "Charlie");
                System.out.println("User name: " + jedis.hget("jedis:user:1002", "name"));
            }
            // The Jedis object is returned to the pool when the try-with-resources block exits
        } finally {
            // The pool is closed and all resources are released
            jedisPool.close();
        }
    }
}

The API for jedis (e.g., jedis.set(), jedis.hgetall()) is almost identical to the synchronous API of Lettuce.

分享:
扫描分享到社交APP
上一篇
下一篇