import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* redis操作类
*/
public class RedisUtils {
private static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);
private static StringRedisTemplate stringRedisTemplate;
static {
stringRedisTemplate=SpringUtil.getBean(StringRedisTemplate.class);
}
/**
* 将参数中的字符串值设置为键的值,不设置过期时间
* @param key
* @param value 必须要实现 Serializable 接口
*/
public static void set(String key, String value) {
stringRedisTemplate.opsForValue().set(key, value);
}
/**
* 将参数中的字符串值设置为键的值,设置过期时间
* @param key
* @param value 必须要实现 Serializable 接口
* @param timeout
*/
public static void set(String key, String value, Long timeout) {
stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
}
/**
* 获取与指定键相关的值
* @param key
* @return
*/
public static Object get(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
/**
* 设置某个键的过期时间
* @param key 键值
* @param ttl 过期秒数
*/
public static boolean expire(String key, Long ttl) {
return stringRedisTemplate.expire(key, ttl, TimeUnit.SECONDS);
}
/**
* 判断某个键是否存在
* @param key 键值
*/
public static boolean hasKey(String key) {
return stringRedisTemplate.hasKey(key);
}
/**
* 向集合添加元素
* @param key
* @param value
* @return 返回值为设置成功的value数
*/
public static Long sAdd(String key, String... value) {
return stringRedisTemplate.opsForSet().add(key, value);
}
/**
* 获取集合中的某个元素
* @param key
* @return 返回值为redis中键值为key的value的Set集合
*/
public static Set<String> sGetMembers(String key) {
return stringRedisTemplate.opsForSet().members(key);
}
//===============================zset=================================
/**
* 根据key获取Set中的所有值
*
* @param key 键
* @return Set
*/
public static Set<String> getZSet(String key) {
try {
return stringRedisTemplate.opsForZSet().range(key, 0, -1);
} catch (Exception e) {
logger.error("redis 操作失败,失败原因:", e);
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public static Double getZSetScore(String key, Object value) {
try {
return stringRedisTemplate.opsForZSet().score(key,value);
} catch (Exception e) {
logger.error("redis 操作失败,失败原因:", e);
return 0d;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public static double setZSet(String key, String values) {
try {
return stringRedisTemplate.opsForZSet().incrementScore(key, values, 1);
} catch (Exception e) {
logger.error("redis 操作失败,失败原因:", e);
return 0;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public static boolean setZSet(String key, String values,double score) {
try {
return stringRedisTemplate.opsForZSet().add(key, values,score);
} catch (Exception e) {
logger.error("redis 操作失败,失败原因:", e);
return false;
}
}
/**
* 删除指定的键
* @param key
* @return
*/
public static Boolean delete(String key) {
return stringRedisTemplate.delete(key);
}
/**
* 删除多个键
* @param keys
* @return
*/
public static Long delete(Collection<String> keys) {
return stringRedisTemplate.delete(keys);
}
/**
* 查询所有的key
* @param matchKey
* @return
*/
public Set<String> scan(String matchKey) {
Set<String> keys = stringRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {
Set<String> keysTmp = new HashSet<>();
Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match("*" + matchKey + "*").count(1000).build());
while (cursor.hasNext()) {
keysTmp.add(new String(cursor.next()));
}
return keysTmp;
});
return keys;
}
/**
* 查询所有的key
* @param matchKey
* @return
*/
public int scanCount(String matchKey,int size) {
int count = stringRedisTemplate.execute((RedisCallback<Integer>) connection -> {
int num=0;
Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match("*" + matchKey + "*").count(size).build());
while (cursor.hasNext()) {
byte[] next = cursor.next();
num += next.length;
}
return num;
});
return count;
}
/**
* 递增
*
* @param key 键
* @return long
*/
public static long incr(String key) {
return stringRedisTemplate.opsForValue().increment(key);
}
/**
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
* @return long
*/
public static long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return stringRedisTemplate.opsForValue().increment(key, delta);
}
/**
* 递增
* @param key 键
* @return long
*/
public static long incrAndExpire(String key,long time) {
return stringRedisTemplate.execute((RedisCallback<Long>) connection -> {
byte[] bytes = key.getBytes(StandardCharsets.UTF_8);
Long incr = connection.incr(bytes);
connection.expire(bytes,time);
return incr;
});
}
/**
* 递增
* @param key 键
* @return long
*/
public static long incrAndExpire(String key,long delta,long time) {
return stringRedisTemplate.execute((RedisCallback<Long>) connection -> {
byte[] bytes = key.getBytes(StandardCharsets.UTF_8);
Long incr = connection.incrBy(bytes,delta);
connection.expire(bytes,time);
return incr;
});
}
/**
* 递减
*
* @param key 键
* @param delta 要减少几(小于0)
* @return long
*/
public static long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return stringRedisTemplate.opsForValue().increment(key, -delta);
}
/**
* 生成公单
* 递增
* @param key 键
* @return long
*/
public static long getOrderIdNum(String key,long delta,long time) {
String format = DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT);
return stringRedisTemplate.execute((RedisCallback<Long>) connection -> {
byte[] bytes = key.getBytes(StandardCharsets.UTF_8);
Long incr = connection.incrBy(bytes,delta);
connection.expire(bytes,time);
return incr;
});
}
}