cn.acyou.leo.framework.util.redis.RedisUtils Maven / Gradle / Ivy
package cn.acyou.leo.framework.util.redis;
import cn.acyou.leo.framework.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.core.query.SortQuery;
import org.springframework.data.redis.core.query.SortQueryBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* Redis 命令参考
* http://doc.redisfans.com/
*
* @author fangyou
* @version [1.0.0, 2021-08-25 13:50]
*/
@Component
public class RedisUtils {
private static final Logger log = LoggerFactory.getLogger(RedisUtils.class);
@Autowired
private StringRedisTemplate redisTemplate;
//私有化构造方法,无法通过new创建。而不影响Spring通过反射创建Bean
private RedisUtils() {
log.info("RedisUtils 初始化完成。");
}
/**
* ZSet 类型操作
*/
public ZSetOperations opsForZset() {
return redisTemplate.opsForZSet();
}
/**
* String 类型操作
*/
public ValueOperations opsForValue() {
return redisTemplate.opsForValue();
}
/**
* Hash 类型操作
*/
public HashOperations opsForHash() {
return redisTemplate.opsForHash();
}
/**
* List 类型操作
*/
public ListOperations opsForList() {
return redisTemplate.opsForList();
}
/**
* Set 类型操作
*/
public SetOperations opsForSet() {
return redisTemplate.opsForSet();
}
/**
* Geo 类型操作 (经纬度)
*/
public GeoOperations opsForGeo() {
return redisTemplate.opsForGeo();
}
/**
* 从当前数据库中随机返回(不删除)一个 key 。
*
* @return 当数据库不为空时,返回一个 key 。
* 当数据库为空时,返回 nil 。
*/
public String randomKey() {
return redisTemplate.randomKey();
}
/**
* 统计存在的键
*
* @param keys 键
* @return 存在的键的数量
*/
public Long countExistingKeys(Collection keys) {
return redisTemplate.countExistingKeys(keys);
}
/**
* 删除
*
* @param keys 键
* @return 删除的数量
*/
public Long delete(Collection keys) {
return redisTemplate.delete(keys);
}
/**
* 删除
*
* @param key 键
* @return 成功/失败
*/
public Boolean delete(String key) {
return redisTemplate.delete(key);
}
/**
* 包含键
*
* @param key 键
* @return 是/否
*/
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 为键设置过期时间
*
* @param key 关键
* @param timeout 超时
* @return 成功/失败
*/
public Boolean expire(String key, Duration timeout) {
return redisTemplate.expire(key, timeout);
}
/**
* 为键设置过期时间
*
* @param key 关键
* @param timeout 时间
* @param unit 单位
* @return 成功/失败
*/
public Boolean expire(String key, long timeout, TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
/**
* 为键设置过期时间
*
* @param key 关键
* @param date 日期
* @return 成功/失败
*/
public Boolean expireAt(String key, Date date) {
return redisTemplate.expireAt(key, date);
}
/**
* 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
*
* @param key 关键
* @return 当 key 不存在时,返回 -2 。
* 当 key 存在但没有设置剩余生存时间时,返回 -1 。
* 否则,以秒为单位,返回 key 的剩余生存时间。
*/
public Long getExpire(String key) {
return redisTemplate.getExpire(key);
}
/**
* 返回给定 key 的剩余生存时间(TTL, time to live)。
*
* @param key 关键
* @param unit 单位
* @return 过期时间
*/
public Long getExpire(String key, TimeUnit unit) {
return redisTemplate.getExpire(key, unit);
}
/**
* 查找所有符合给定模式 pattern 的 key 。
*
* KEYS * 匹配数据库中所有 key 。
* KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
* KEYS h*llo 匹配 hllo 和 heeeeello 等。
* KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。
* 特殊符号用 \ 隔开
*
*
* @param pattern 模式
* @return 符合给定模式的 key 列表。
*/
public Set keys(String pattern) {
return redisTemplate.keys(pattern);
}
/**
* 移除给定 key 的生存时间,将这个 key 从『易失的』(带生存时间 key )转换成『持久的』(一个不带生存时间、永不过期的 key )。
*
* @param key 关键
* @return 当生存时间移除成功时,返回 1 .
* 如果 key 不存在或 key 没有设置生存时间,返回 0 。
*/
public Boolean persist(String key) {
return redisTemplate.persist(key);
}
/**
* 将 key 改名为 newkey 。
* 当 key 和 newkey 相同,或者 key 不存在时,返回一个错误。
* 当 newkey 已经存在时, RENAME 命令将覆盖旧值。
*
* 改名成功时提示 OK ,失败时候返回一个错误。
*
* @param oldKey 旧的关键
* @param newKey 新的密钥
*/
public void rename(String oldKey, String newKey) {
redisTemplate.rename(oldKey, newKey);
}
/**
* 当且仅当 newkey 不存在时,将 key 改名为 newkey 。
*
* @param oldKey 旧的关键
* @param newKey 新的密钥
* @return 修改成功时,返回 1 。
* 如果 newkey 已经存在,返回 0 。
*/
public Boolean renameIfAbsent(String oldKey, String newKey) {
return redisTemplate.renameIfAbsent(oldKey, newKey);
}
/**
* 排序
*
* @param key 关键
* @param order 排序
* @param pageNum 页码
* @param pageSize 页面大小
* @return 元素
*/
public List sort(String key, SortParameters.Order order, long pageNum, long pageSize) {
long offset = (pageNum - 1) * pageSize;
SortQuery sortQuery = SortQueryBuilder.sort(key).order(order).limit(offset, pageSize).build();
return redisTemplate.sort(sortQuery);
}
/**
* 返回 key 所储存的值的类型。
*
* @param key 关键
* @return 类型
*/
public DataType type(String key) {
return redisTemplate.type(key);
}
/**
* 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。
*
* 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
*
* @param key 键
* @param value 值
* @return 追加 value 之后, key 中字符串的长度。
*/
public Integer append(String key, String value) {
return redisTemplate.opsForValue().append(key, value);
}
/**
* 将 key 中储存的数字值减一。
*
* 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。
*
* @param key 关键
* @return 执行 DECR 命令之后 key 的值。
*/
public Long decrement(String key) {
return redisTemplate.opsForValue().decrement(key);
}
/**
* 将 key 所储存的值减去减量 decrement 。
*
* @param key 关键
* @param deal 减量
* @return 减去 decrement 之后, key 的值。
*/
public Long decrement(String key, long deal) {
return redisTemplate.opsForValue().decrement(key, deal);
}
/**
* 将 key 中储存的数字值增一。
*
* 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
*
* @param key 关键
* @return 执行 INCR 命令之后 key 的值。
*/
public Long increment(String key) {
return redisTemplate.opsForValue().increment(key);
}
/**
* 将 key 所储存的值加上增量 increment 。
*
* 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。
*
* @param key 键
* @param deal 增量
* @return 加上 increment 之后, key 的值。
*/
public Long increment(String key, long deal) {
return redisTemplate.opsForValue().increment(key, deal);
}
/**
* 自增 / 自减 并在初始时设置过期时间
* 保证原子性:初始化值为1的时候必设置过期时间。
* @param key key
* @param delta 1自增1 -1减少1
* @param timeOut 超时时间(单位秒)
* @return 执行 INCR 命令之后 key 的值。
*/
public Long increment(String key, long delta, long timeOut) {
SessionCallback sessionCallback = new SessionCallback() {
@Override
public Long execute(RedisOperations operations) throws DataAccessException {
operations.multi();
redisTemplate.opsForValue().increment(key, delta);
List> exec = operations.exec();
Long incValue = (Long) exec.get(0);
if (incValue != null && incValue == 1){
redisTemplate.expire(key, timeOut, TimeUnit.SECONDS);
}
return incValue;
}
};
return redisTemplate.execute(sessionCallback);
}
/**
* 返回 key 所关联的字符串值。
*
* @param key 关键
* @return 当 key 不存在时,返回 nil ,否则,返回 key 的值。
* 如果 key 不是字符串类型,那么返回一个错误。
*/
public String get(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
*
* @param key 键
* @param value 值
* @return 返回给定 key 的旧值。
*/
public String getAndSet(String key, String value) {
return redisTemplate.opsForValue().getAndSet(key, value);
}
/**
* 返回所有(一个或多个)给定 key 的值。
*
* @param keys 键
* @return 一个包含所有给定 key 的值的列表。
*/
public List multiGet(Collection keys) {
return redisTemplate.opsForValue().multiGet(keys);
}
/**
* 同时设置一个或多个 key-value 对。
*
* @param keyValues 键值
*/
public void multiSet(Map keyValues) {
redisTemplate.opsForValue().multiSet(keyValues);
}
/**
* 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
*
* @param keyValues 键值
* @return 成功/失败
*/
public Boolean multiSetIfAbsent(Map keyValues) {
return redisTemplate.opsForValue().multiSetIfAbsent(keyValues);
}
/**
* 将字符串值 value 关联到 key 。
*
* 如果 key 已经持有其他值, SET 就覆写旧值,无视类型。
*
* 对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。
*
* @param key 关键
* @param value 价值
*/
public void set(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 将值 value 关联到 key ,并设置 key 的生存时间。
*
* @param key 键
* @param value 值
* @param timeout 超时
* @param unit 单位
*/
public void set(String key, String value, long timeout, TimeUnit unit) {
redisTemplate.opsForValue().set(key, value, timeout, unit);
}
/**
* 将 key 的值设为 value ,当且仅当 key 不存在。
*
* @param key 关键
* @param value 价值
*/
public Boolean setIfAbsent(String key, String value) {
return redisTemplate.opsForValue().setIfAbsent(key, value);
}
/**
* 将 key 的值设为 value ,当且仅当 key 不存在。并设置 key 的生存时间。
*
* @param key 关键
* @param value 价值
* @param timeout 超时
* @param unit 单位
*/
public Boolean setIfAbsent(String key, String value, long timeout, TimeUnit unit) {
return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit);
}
/**
* 如果存在设置
*
* @param key 关键
* @param value 价值
*/
public Boolean setIfPresent(String key, String value) {
return redisTemplate.opsForValue().setIfPresent(key, value);
}
/**
* 如果存在设置,并设置 key 的生存时间。
*
* @param key 关键
* @param value 价值
* @param timeout 超时
* @param unit 单位
*/
public Boolean setIfPresent(String key, String value, long timeout, TimeUnit unit) {
return redisTemplate.opsForValue().setIfPresent(key, value, timeout, unit);
}
/**
* 获取值的长度:STRLEN
*
* @param key 关键
* @return 值的长度
*/
public Long size(String key) {
return redisTemplate.opsForValue().size(key);
}
/*
* ——————————————————————————Hash——————————————————————————————
*/
/**
* 散列的大小
*
* @param key 关键
* @return 所有hash键的数量
*/
public Long hashSize(String key) {
return redisTemplate.opsForHash().size(key);
}
/**
* 散列删除
*
* @param key 关键
* @param hashKeys 散列键
* @return 已删除的数量
*/
public Long hashDelete(String key, Object... hashKeys) {
return redisTemplate.opsForHash().delete(key, hashKeys);
}
/**
* 散列有关键
*
* @param key 关键
* @param hashKeys 散列键
* @return 是/否
*/
public Boolean hashHasKey(String key, Object hashKeys) {
return redisTemplate.opsForHash().hasKey(key, hashKeys);
}
/**
* 哈希得到
*
* @param key 关键
* @param hashKeys 散列键
* @return 哈希值
*/
public Object hashGet(String key, Object hashKeys) {
return redisTemplate.opsForHash().get(key, hashKeys);
}
/**
* 散列多得到
*
* @param key 关键
* @param hashKeys 散列键
* @return 哈希值列表
*/
public List