本文目录导读:

我来给你一个完整的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配置修改连接参数。