Java Redis案例如何Java实操

wen java案例 30

本文目录导读:

Java Redis案例如何Java实操

  1. 环境准备
  2. Redis连接配置类
  3. 基础数据操作案例
  4. 实际业务场景案例
  5. 使用示例

我来给你一个完整的Java操作Redis的实操案例,包含常用的数据操作场景。

环境准备

Maven依赖

<!-- Redis客户端 -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.1</version>
</dependency>
<!-- 如果需要连接池 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.11.1</version>
</dependency>
<!-- JSON处理(可选) -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.25</version>
</dependency>

Redis连接配置类

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisConfig {
    private static JedisPool jedisPool;
    static {
        initPool();
    }
    private static void initPool() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        // 最大连接数
        poolConfig.setMaxTotal(8);
        // 最大空闲连接数
        poolConfig.setMaxIdle(8);
        // 最小空闲连接数
        poolConfig.setMinIdle(0);
        // 获取连接时的最大等待毫秒数
        poolConfig.setMaxWaitMillis(1000);
        // 测试连接是否可用
        poolConfig.setTestOnBorrow(true);
        // 创建连接池(根据实际情况修改主机和端口)
        jedisPool = new JedisPool(poolConfig, "localhost", 6379, 2000, "your_password");
    }
    // 获取Redis连接
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
    // 关闭连接
    public static void closeJedis(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }
    // 关闭连接池
    public static void closePool() {
        if (jedisPool != null && !jedisPool.isClosed()) {
            jedisPool.close();
        }
    }
}

基础数据操作案例

import redis.clients.jedis.Jedis;
import java.util.*;
public class RedisBasicOperations {
    public static void main(String[] args) {
        Jedis jedis = null;
        try {
            // 获取连接
            jedis = RedisConfig.getJedis();
            // ========== 字符串操作 ==========
            System.out.println("=== 字符串操作 ===");
            // 设置值
            jedis.set("name", "张三");
            jedis.set("age", "25");
            // 获取值
            String name = jedis.get("name");
            System.out.println("name: " + name);
            // 设置过期时间(10秒)
            jedis.setex("token", 10, "abc123");
            // 自增操作
            jedis.incr("visit_count");
            jedis.incrBy("visit_count", 5);
            System.out.println("访问次数: " + jedis.get("visit_count"));
            // ========== 哈希操作 ==========
            System.out.println("\n=== 哈希操作 ===");
            // 设置哈希值
            jedis.hset("user:1", "name", "李四");
            jedis.hset("user:1", "age", "30");
            jedis.hset("user:1", "city", "北京");
            // 获取哈希值
            String userName = jedis.hget("user:1", "name");
            System.out.println("用户1名称: " + userName);
            // 获取所有字段
            Map<String, String> userMap = jedis.hgetAll("user:1");
            System.out.println("用户1信息: " + userMap);
            // 批量设置
            Map<String, String> user2 = new HashMap<>();
            user2.put("name", "王五");
            user2.put("age", "28");
            user2.put("city", "上海");
            jedis.hset("user:2", user2);
            // ========== 列表操作 ==========
            System.out.println("\n=== 列表操作 ===");
            // 添加元素到列表
            jedis.lpush("mylist", "A", "B", "C");
            jedis.rpush("mylist", "D", "E");
            // 获取列表范围
            List<String> list = jedis.lrange("mylist", 0, -1);
            System.out.println("列表内容: " + list);
            // 弹出元素
            String popLeft = jedis.lpop("mylist");
            System.out.println("左侧弹出: " + popLeft);
            // 获取列表长度
            Long listLength = jedis.llen("mylist");
            System.out.println("列表长度: " + listLength);
            // ========== 集合操作 ==========
            System.out.println("\n=== 集合操作 ===");
            // 添加元素
            jedis.sadd("myset", "a", "b", "c", "a"); // a会被去重
            jedis.sadd("myset", "d");
            // 获取所有元素
            Set<String> set = jedis.smembers("myset");
            System.out.println("集合内容: " + set);
            // 判断元素是否存在
            boolean exists = jedis.sismember("myset", "a");
            System.out.println("元素a是否存在: " + exists);
            // ========== 有序集合操作 ==========
            System.out.println("\n=== 有序集合操作 ===");
            // 添加元素(带分数)
            jedis.zadd("ranking", 100, "用户A");
            jedis.zadd("ranking", 80, "用户B");
            jedis.zadd("ranking", 95, "用户C");
            // 获取排名(按分数从高到低)
            Set<String> ranking = jedis.zrevrange("ranking", 0, -1);
            System.out.println("排行榜: " + ranking);
            // 获取分数
            Double score = jedis.zscore("ranking", "用户A");
            System.out.println("用户A分数: " + score);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接
            RedisConfig.closeJedis(jedis);
        }
    }
}

实际业务场景案例

1 缓存用户信息

import com.alibaba.fastjson.JSON;
import java.util.concurrent.TimeUnit;
public class UserCacheService {
    // 模拟数据库查询
    private User getUserFromDB(Long userId) {
        // 实际场景中这里会查询数据库
        User user = new User();
        user.setId(userId);
        user.setName("用户" + userId);
        user.setEmail("user" + userId + "@example.com");
        user.setCreateTime(new Date());
        return user;
    }
    // 获取用户信息(带缓存)
    public User getUser(Long userId) {
        Jedis jedis = null;
        try {
            jedis = RedisConfig.getJedis();
            String key = "user:" + userId;
            // 1. 先从缓存获取
            String json = jedis.get(key);
            if (json != null) {
                // 缓存命中
                System.out.println("从缓存获取用户: " + userId);
                return JSON.parseObject(json, User.class);
            }
            // 2. 缓存未命中,从数据库查询
            System.out.println("从数据库查询用户: " + userId);
            User user = getUserFromDB(userId);
            // 3. 写入缓存(设置1小时过期)
            String userJson = JSON.toJSONString(user);
            jedis.setex(key, 3600, userJson);
            return user;
        } catch (Exception e) {
            e.printStackTrace();
            // 缓存异常时,直接查询数据库
            return getUserFromDB(userId);
        } finally {
            RedisConfig.closeJedis(jedis);
        }
    }
    // 更新用户信息
    public void updateUser(User user) {
        Jedis jedis = null;
        try {
            jedis = RedisConfig.getJedis();
            String key = "user:" + user.getId();
            // 1. 更新数据库(这里使用打印模拟)
            System.out.println("更新数据库用户: " + user.getId());
            // updateDB(user);
            // 2. 删除缓存
            jedis.del(key);
            System.out.println("删除缓存: " + key);
        } finally {
            RedisConfig.closeJedis(jedis);
        }
    }
}

2 分布式锁实现

public class RedisDistributedLock {
    private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";
    private static final Long RELEASE_SUCCESS = 1L;
    /**
     * 获取分布式锁
     * @param lockKey 锁的key
     * @param requestId 请求标识(用于释放锁时验证)
     * @param expireTime 过期时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryGetLock(String lockKey, String requestId, int expireTime) {
        Jedis jedis = null;
        try {
            jedis = RedisConfig.getJedis();
            String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
            return LOCK_SUCCESS.equals(result);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            RedisConfig.closeJedis(jedis);
        }
    }
    /**
     * 释放分布式锁(使用Lua脚本保证原子性)
     * @param lockKey 锁的key
     * @param requestId 请求标识
     * @return 是否释放成功
     */
    public boolean releaseLock(String lockKey, String requestId) {
        Jedis jedis = null;
        try {
            jedis = RedisConfig.getJedis();
            // Lua脚本:比对value是否匹配,匹配则删除
            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                           "return redis.call('del', KEYS[1]) " +
                           "else return 0 end";
            Object result = jedis.eval(script, 
                Collections.singletonList(lockKey),
                Collections.singletonList(requestId));
            return RELEASE_SUCCESS.equals(result);
        } finally {
            RedisConfig.closeJedis(jedis);
        }
    }
}

3 限流器实现

public class RedisRateLimiter {
    /**
     * 滑动窗口限流
     * @param key 限流key
     * @param maxCount 最大访问次数
     * @param windowSeconds 窗口大小(秒)
     * @return 是否允许访问
     */
    public boolean allowAccess(String key, int maxCount, int windowSeconds) {
        Jedis jedis = null;
        try {
            jedis = RedisConfig.getJedis();
            long now = System.currentTimeMillis();
            // 移除窗口外的记录
            jedis.zremrangeByScore(key, 0, now - windowSeconds * 1000);
            // 统计当前窗口内的请求数
            Long count = jedis.zcard(key);
            if (count >= maxCount) {
                return false;
            }
            // 添加当前请求
            jedis.zadd(key, now, String.valueOf(now));
            // 设置过期时间
            jedis.expire(key, windowSeconds);
            return true;
        } finally {
            RedisConfig.closeJedis(jedis);
        }
    }
    /**
     * 令牌桶限流
     * @param key 限流key
     * @param maxTokens 最大令牌数
     * @param rate 令牌生成速率(个/秒)
     */
    public boolean tryAcquire(String key, int maxTokens, int rate) {
        Jedis jedis = null;
        try {
            jedis = RedisConfig.getJedis();
            String luaScript = 
                "local key = KEYS[1]\n" +
                "local maxTokens = tonumber(ARGV[1])\n" +
                "local rate = tonumber(ARGV[2])\n" +
                "local now = tonumber(ARGV[3])\n" +
                "local lastRefillTime = redis.call('hget', key, 'lastRefillTime')\n" +
                "local tokens = redis.call('hget', key, 'tokens')\n" +
                "if lastRefillTime == false then\n" +
                "    lastRefillTime = now\n" +
                "    tokens = maxTokens\n" +
                "end\n" +
                "local timeSinceRefill = now - tonumber(lastRefillTime)\n" +
                "local tokensToAdd = math.floor(timeSinceRefill * rate / 1000)\n" +
                "tokens = math.min(maxTokens, tonumber(tokens) + tokensToAdd)\n" +
                "lastRefillTime = now\n" +
                "if tokens < 1 then\n" +
                "    redis.call('hset', key, 'lastRefillTime', lastRefillTime)\n" +
                "    redis.call('hset', key, 'tokens', tokens)\n" +
                "    return 0\n" +
                "else\n" +
                "    tokens = tokens - 1\n" +
                "    redis.call('hset', key, 'lastRefillTime', lastRefillTime)\n" +
                "    redis.call('hset', key, 'tokens', tokens)\n" +
                "    redis.call('expire', key, 10)\n" +
                "    return 1\n" +
                "end";
            Object result = jedis.eval(luaScript, 
                Collections.singletonList(key),
                Arrays.asList(
                    String.valueOf(maxTokens),
                    String.valueOf(rate),
                    String.valueOf(System.currentTimeMillis())
                ));
            return "1".equals(String.valueOf(result));
        } finally {
            RedisConfig.closeJedis(jedis);
        }
    }
}

使用示例

public class RedisDemo {
    public static void main(String[] args) {
        // 1. 基础操作测试
        RedisBasicOperations.main(null);
        // 2. 缓存服务测试
        UserCacheService cacheService = new UserCacheService();
        User user = cacheService.getUser(1L);
        System.out.println("获取用户: " + user.getName());
        // 3. 分布式锁测试
        RedisDistributedLock lock = new RedisDistributedLock();
        String requestId = UUID.randomUUID().toString();
        boolean locked = lock.tryGetLock("order:123", requestId, 30000);
        if (locked) {
            System.out.println("获取锁成功");
            try {
                // 执行业务逻辑
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.releaseLock("order:123", requestId);
            }
        }
        // 4. 限流测试
        RedisRateLimiter limiter = new RedisRateLimiter();
        String apiKey = "api:user_login";
        for (int i = 0; i < 15; i++) {
            boolean allowed = limiter.allowAccess(apiKey, 10, 60);
            System.out.println("请求" + (i+1) + ": " + (allowed ? "通过" : "被限流"));
        }
        // 关闭连接池
        RedisConfig.closePool();
    }
}
// 辅助类
class User {
    private Long id;
    private String name;
    private String email;
    private Date createTime;
    // getter和setter方法...
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public Date getCreateTime() { return createTime; }
    public void setCreateTime(Date createTime) { this.createTime = createTime; }
}

这个案例涵盖了Redis在Java中的主要应用场景,包括数据缓存、分布式锁和限流等实际业务需求,记得根据你的实际Redis配置修改连接参数。

抱歉,评论功能暂时关闭!