Files
FlashSaleSystem/src/main/java/com/org/flashsalesystem/service/RedisService.java
2025-07-02 22:39:21 +08:00

387 lines
9.6 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.org.flashsalesystem.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* Redis服务类
* 封装Redis的各种操作包括五种数据类型的应用
*/
@Service
@Slf4j
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
@Qualifier("customStringRedisTemplate")
private RedisTemplate<String, String> stringRedisTemplate;
@Autowired
private DefaultRedisScript<Long> flashSaleScript;
@Autowired
private DefaultRedisScript<String> lockScript;
@Autowired
private DefaultRedisScript<Long> unlockScript;
// ========== String类型操作 ==========
/**
* 设置字符串值
*/
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 设置纯字符串值用于Lua脚本兼容
*/
public void setString(String key, String value) {
stringRedisTemplate.opsForValue().set(key, value);
}
/**
* 设置字符串值并指定过期时间
*/
public void set(String key, Object value, long timeout, TimeUnit unit) {
redisTemplate.opsForValue().set(key, value, timeout, unit);
}
/**
* 获取字符串值
*/
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* 安全获取字符串值
*/
public String getString(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
/**
* 原子递增
*/
public Long incr(String key) {
return redisTemplate.opsForValue().increment(key);
}
/**
* 原子递增指定步长
*/
public Long incrBy(String key, long delta) {
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 原子递减
*/
public Long decr(String key) {
return redisTemplate.opsForValue().decrement(key);
}
/**
* 原子递减指定步长
*/
public Long decrBy(String key, long delta) {
return redisTemplate.opsForValue().decrement(key, delta);
}
/**
* 设置键值,仅当键不存在时
*/
public Boolean setNx(String key, Object value) {
return redisTemplate.opsForValue().setIfAbsent(key, value);
}
/**
* 设置键值和过期时间,仅当键不存在时
*/
public Boolean setNx(String key, Object value, long timeout, TimeUnit unit) {
return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit);
}
// ========== Hash类型操作 ==========
/**
* 设置Hash字段值
*/
public void hSet(String key, String field, Object value) {
redisTemplate.opsForHash().put(key, field, value);
}
/**
* 获取Hash字段值
*/
public Object hGet(String key, String field) {
return redisTemplate.opsForHash().get(key, field);
}
/**
* 批量设置Hash字段
*/
public void hMSet(String key, Map<String, Object> map) {
redisTemplate.opsForHash().putAll(key, map);
}
/**
* 批量获取Hash字段值
*/
public List<Object> hMGet(String key, Collection<Object> fields) {
return redisTemplate.opsForHash().multiGet(key, fields);
}
/**
* 获取Hash所有字段和值
*/
public Map<Object, Object> hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* 删除Hash字段
*/
public Long hDel(String key, Object... fields) {
return redisTemplate.opsForHash().delete(key, fields);
}
/**
* 检查Hash字段是否存在
*/
public Boolean hExists(String key, String field) {
return redisTemplate.opsForHash().hasKey(key, field);
}
/**
* Hash字段值递增
*/
public Long hIncrBy(String key, String field, long delta) {
return redisTemplate.opsForHash().increment(key, field, delta);
}
/**
* 获取Hash长度
*/
public Long hLen(String key) {
return redisTemplate.opsForHash().size(key);
}
// ========== List类型操作 ==========
/**
* 从左侧推入元素
*/
public Long lPush(String key, Object... values) {
return redisTemplate.opsForList().leftPushAll(key, values);
}
/**
* 从右侧推入元素
*/
public Long rPush(String key, Object... values) {
return redisTemplate.opsForList().rightPushAll(key, values);
}
/**
* 从左侧弹出元素
*/
public Object lPop(String key) {
return redisTemplate.opsForList().leftPop(key);
}
/**
* 从右侧弹出元素
*/
public Object rPop(String key) {
return redisTemplate.opsForList().rightPop(key);
}
/**
* 获取列表长度
*/
public Long lLen(String key) {
return redisTemplate.opsForList().size(key);
}
/**
* 获取列表指定范围的元素
*/
public List<Object> lRange(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
}
// ========== Set类型操作 ==========
/**
* 添加元素到集合
*/
public Long sAdd(String key, Object... values) {
return redisTemplate.opsForSet().add(key, values);
}
/**
* 从集合中移除元素
*/
public Long sRem(String key, Object... values) {
return redisTemplate.opsForSet().remove(key, values);
}
/**
* 检查元素是否在集合中
*/
public Boolean sIsMember(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}
/**
* 获取集合所有元素
*/
public Set<Object> sMembers(String key) {
return redisTemplate.opsForSet().members(key);
}
/**
* 获取集合大小
*/
public Long sCard(String key) {
return redisTemplate.opsForSet().size(key);
}
// ========== ZSet类型操作 ==========
/**
* 添加元素到有序集合
*/
public Boolean zAdd(String key, Object value, double score) {
return redisTemplate.opsForZSet().add(key, value, score);
}
/**
* 从有序集合中移除元素
*/
public Long zRem(String key, Object... values) {
return redisTemplate.opsForZSet().remove(key, values);
}
/**
* 获取有序集合指定范围的元素(按分数排序)
*/
public Set<Object> zRange(String key, long start, long end) {
return redisTemplate.opsForZSet().range(key, start, end);
}
/**
* 获取有序集合指定范围的元素(按分数倒序)
*/
public Set<Object> zRevRange(String key, long start, long end) {
return redisTemplate.opsForZSet().reverseRange(key, start, end);
}
/**
* 增加有序集合元素的分数
*/
public Double zIncrBy(String key, Object value, double delta) {
return redisTemplate.opsForZSet().incrementScore(key, value, delta);
}
/**
* 获取有序集合大小
*/
public Long zCard(String key) {
return redisTemplate.opsForZSet().zCard(key);
}
// ========== 通用操作 ==========
/**
* 删除键
*/
public Boolean delete(String key) {
return redisTemplate.delete(key);
}
/**
* 批量删除键
*/
public Long delete(Collection<String> keys) {
return redisTemplate.delete(keys);
}
/**
* 检查键是否存在
*/
public Boolean exists(String key) {
return redisTemplate.hasKey(key);
}
/**
* 设置键的过期时间
*/
public Boolean expire(String key, long timeout, TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
/**
* 获取键的剩余过期时间
*/
public Long getExpire(String key) {
return redisTemplate.getExpire(key);
}
// ========== Lua脚本操作 ==========
/**
* 执行秒杀脚本
*/
public Long executeFlashSaleScript(String stockKey, int quantity) {
log.info("执行秒杀脚本: stockKey={}, quantity={}", stockKey, quantity);
try {
Long result = stringRedisTemplate.execute(flashSaleScript, Collections.singletonList(stockKey),
String.valueOf(quantity));
log.info("秒杀脚本执行结果: result={}", result);
return result;
} catch (Exception e) {
log.error("执行秒杀脚本异常: stockKey={}, quantity={}", stockKey, quantity, e);
throw e;
}
}
/**
* 执行分布式锁脚本
*/
public String executeLockScript(String lockKey, String lockValue, int expireSeconds) {
return redisTemplate.execute(lockScript, Collections.singletonList(lockKey), lockValue,
String.valueOf(expireSeconds));
}
/**
* 执行释放锁脚本
*/
public Long executeUnlockScript(String lockKey, String lockValue) {
return redisTemplate.execute(unlockScript, Collections.singletonList(lockKey), lockValue);
}
// ========== 发布订阅操作 ==========
/**
* 发布消息
*/
public void publish(String channel, Object message) {
redisTemplate.convertAndSend(channel, message);
}
}