← 返回首页

Java Redis操作详解

📂 java ⏱ 3 min 480 words

Java Redis操作详解

Redis客户端选择

客户端 特点 适用场景
Jedis 同步阻塞,简单直接 小项目、简单场景
Lettuce 基于Netty,异步非阻塞 Spring Boot默认,推荐使用
Redisson 高级封装,分布式支持 分布式锁、队列

Lettuce使用

依赖配置

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.3.0.RELEASE</version>
</dependency>

基本操作

import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;

public class RedisDemo {
    public static void main(String[] args) {
        RedisClient client = RedisClient.create("redis://localhost:6379");
        StatefulRedisConnection<String, String> connection = client.connect();
        RedisCommands<String, String> commands = connection.sync();

        // String操作
        commands.set("name", "张三");
        String name = commands.get("name");
        System.out.println(name);

        commands.set("counter", "0");
        commands.incr("counter");
        commands.incrBy("counter", 5);

        // 带过期时间
        commands.set("token", "abc123", SetArgs.Builder.ex(3600));

        connection.close();
        client.shutdown();
    }
}

Hash操作

public class RedisHash {
    public static void main(String[] args) {
        RedisClient client = RedisClient.create("redis://localhost:6379");
        StatefulRedisConnection<String, String> conn = client.connect();
        RedisCommands<String, String> cmd = conn.sync();

        // Hash操作
        cmd.hset("user:1", "name", "张三");
        cmd.hset("user:1", "age", "25");
        cmd.hset("user:1", "email", "zhangsan@example.com");

        Map<String, String> user = cmd.hgetall("user:1");
        System.out.println(user);

        String name = cmd.hget("user:1", "name");
        cmd.hdel("user:1", "email");
    }
}

List操作

public class RedisList {
    public static void main(String[] args) {
        RedisClient client = RedisClient.create("redis://localhost:6379");
        StatefulRedisConnection<String, String> conn = client.connect();
        RedisCommands<String, String> cmd = conn.sync();

        // List操作
        cmd.lpush("queue", "task1", "task2", "task3");
        String task = cmd.rpop("queue");  // FIFO
        long size = cmd.llen("queue");

        List<String> items = cmd.lrange("queue", 0, -1);
    }
}

Set操作

public class RedisSet {
    public static void main(String[] args) {
        RedisClient client = RedisClient.create("redis://localhost:6379");
        StatefulRedisConnection<String, String> conn = client.connect();
        RedisCommands<String, String> cmd = conn.sync();

        // Set操作
        cmd.sadd("tags", "java", "redis", "spring");
        boolean exists = cmd.sismember("tags", "java");
        Set<String> allTags = cmd.smembers("tags");

        // 交集、并集、差集
        cmd.sadd("user1:tags", "java", "python");
        cmd.sadd("user2:tags", "java", "go");
        Set<String> common = cmd.sinter("user1:tags", "user2:tags");
    }
}

Spring Data Redis

@Configuration
@EnableCaching
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
    }
}

@Service
public class CacheService {
    private final RedisTemplate<String, Object> redisTemplate;

    public CacheService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void set(String key, Object value, long timeout) {
        redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }

    public <T> T get(String key, Class<T> type) {
        return type.cast(redisTemplate.opsForValue().get(key));
    }

    public void delete(String key) {
        redisTemplate.delete(key);
    }
}

分布式锁

@Component
public class RedisLock {
    private final StringRedisTemplate redisTemplate;

    public RedisLock(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public boolean tryLock(String key, String value, long expireSeconds) {
        return Boolean.TRUE.equals(
            redisTemplate.opsForValue().setIfAbsent(key, value, expireSeconds, TimeUnit.SECONDS)
        );
    }

    public void unlock(String key, String value) {
        String script = """
            if redis.call('get', KEYS[1]) == ARGV[1] then
                return redis.call('del', KEYS[1])
            else
                return 0
            end
            """;
        redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),
            List.of(key), value);
    }
}

// 使用
@Component
public class OrderService {
    private final RedisLock redisLock;

    public void createOrder(String orderId) {
        String lockKey = "order:lock:" + orderId;
        String lockValue = UUID.randomUUID().toString();

        if (redisLock.tryLock(lockKey, lockValue, 30)) {
            try {
                // 业务逻辑
            } finally {
                redisLock.unlock(lockKey, lockValue);
            }
        } else {
            throw new RuntimeException("获取锁失败");
        }
    }
}

发布订阅

public class PubSubDemo {
    public static void main(String[] args) {
        RedisClient client = RedisClient.create("redis://localhost:6379");
        StatefulRedisConnection<String, String> pubConn = client.connect();
        StatefulRedisConnection<String, String> subConn = client.connect();

        // 订阅
        subConn.sync().subscribe("notifications");

        // 发布
        pubConn.async().publish("notifications", "新消息: 用户登录");

        pubConn.close();
        subConn.close();
        client.shutdown();
    }
}

总结

Redis是Java应用中最常用的缓存和数据存储。掌握String、Hash、List、Set等数据结构的操作,以及分布式锁和发布订阅的实现,是构建高性能应用的基础。