package com.kidgrow.redis.template;
|
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.collections4.CollectionUtils;
|
import org.springframework.data.redis.connection.RedisClusterNode;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisServerCommands;
|
import org.springframework.data.redis.core.HashOperations;
|
import org.springframework.data.redis.core.ListOperations;
|
import org.springframework.data.redis.core.RedisCallback;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
|
import org.springframework.data.redis.serializer.RedisSerializer;
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
|
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
import java.util.*;
|
import java.util.concurrent.TimeUnit;
|
|
/**
|
* 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
|
*
|
* @Description: Redis基本操作<br>
|
* @Project: <br>
|
* @CreateDate: Created in 2020/2/4 16:05 <br>
|
* @Author: <a href="4345453@kidgrow.com">liuke</a>
|
*/
|
@Slf4j
|
public class RedisRepository {
|
/**
|
* 默认编码
|
*/
|
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
|
|
/**
|
* key序列化
|
*/
|
private static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer();
|
|
/**
|
* value 序列化
|
*/
|
//private static final GenericJackson2JsonRedisSerializer OBJECT_SERIALIZER = new GenericJackson2JsonRedisSerializer();
|
// private static final Jackson2JsonRedisSerializer OBJECT_SERIALIZER = new Jackson2JsonRedisSerializer(Object.class);
|
// private static final FastJsonRedisSerializer OBJECT_SERIALIZER = new FastJsonRedisSerializer(Object.class);
|
|
private static final JdkSerializationRedisSerializer OBJECT_SERIALIZER = new JdkSerializationRedisSerializer();
|
|
|
/**
|
* Spring Redis Template
|
*/
|
private RedisTemplate<String, Object> redisTemplate;
|
|
public RedisRepository(RedisTemplate<String, Object> redisTemplate) {
|
this.redisTemplate = redisTemplate;
|
this.redisTemplate.setKeySerializer(STRING_SERIALIZER);
|
this.redisTemplate.setValueSerializer(OBJECT_SERIALIZER);
|
}
|
|
/**
|
* 获取链接工厂
|
*/
|
public RedisConnectionFactory getConnectionFactory() {
|
return this.redisTemplate.getConnectionFactory();
|
}
|
|
/**
|
* 获取 RedisTemplate对象
|
*/
|
public RedisTemplate<String, Object> getRedisTemplate() {
|
return redisTemplate;
|
}
|
|
/**
|
* 清空DB
|
*
|
* @param node redis 节点
|
*/
|
public void flushDB(RedisClusterNode node) {
|
this.redisTemplate.opsForCluster().flushDb(node);
|
}
|
|
/**
|
* 添加到带有 过期时间的 缓存
|
*
|
* @param key redis主键
|
* @param value 值
|
* @param time 过期时间(单位秒)
|
*/
|
public void setExpire(final byte[] key, final byte[] value, final long time) {
|
redisTemplate.execute((RedisCallback<Long>) connection -> {
|
connection.setEx(key, time, value);
|
log.debug("[redisTemplate redis]放入 缓存 url:{} ========缓存时间为{}秒", key, time);
|
return 1L;
|
});
|
}
|
|
/**
|
* 添加到带有 过期时间的 缓存
|
*
|
* @param key redis主键
|
* @param value 值
|
* @param time 过期时间(单位秒)
|
*/
|
public void setExpire(final String key, final Object value, final long time) {
|
redisTemplate.execute((RedisCallback<Long>) connection -> {
|
RedisSerializer<String> serializer = getRedisSerializer();
|
byte[] keys = serializer.serialize(key);
|
byte[] values = OBJECT_SERIALIZER.serialize(value);
|
if (keys != null && values != null) {
|
connection.setEx(keys, time, values);
|
}
|
return 1L;
|
});
|
}
|
|
/**
|
* 获取key的过期时间
|
* @param key
|
* @return
|
*/
|
public Long getKeyExpire(final String key){
|
Long expire = redisTemplate.getExpire(key);
|
return expire;
|
}
|
|
/**
|
* 一次性添加数组到 过期时间的 缓存,不用多次连接,节省开销
|
*
|
* @param keys redis主键数组
|
* @param values 值数组
|
* @param time 过期时间(单位秒)
|
*/
|
public void setExpire(final String[] keys, final Object[] values, final long time) {
|
redisTemplate.execute((RedisCallback<Long>) connection -> {
|
RedisSerializer<String> serializer = getRedisSerializer();
|
for (int i = 0; i < keys.length; i++) {
|
byte[] bKeys = serializer.serialize(keys[i]);
|
byte[] bValues = OBJECT_SERIALIZER.serialize(values[i]);
|
if (bKeys != null && bValues != null) {
|
connection.setEx(bKeys, time, bValues);
|
}
|
}
|
return 1L;
|
});
|
}
|
|
/**
|
* 一次性添加数组到 过期时间的 缓存,不用多次连接,节省开销
|
*
|
* @param keys the keys
|
* @param values the values
|
*/
|
public void set(final String[] keys, final Object[] values) {
|
redisTemplate.execute((RedisCallback<Long>) connection -> {
|
RedisSerializer<String> serializer = getRedisSerializer();
|
for (int i = 0; i < keys.length; i++) {
|
byte[] bKeys = serializer.serialize(keys[i]);
|
byte[] bValues = OBJECT_SERIALIZER.serialize(values[i]);
|
if (bKeys != null && bValues != null) {
|
connection.set(bKeys, bValues);
|
}
|
}
|
return 1L;
|
});
|
}
|
|
|
/**
|
* 添加到缓存
|
*
|
* @param key the key
|
* @param value the value
|
*/
|
public void set(final String key, final Object value) {
|
redisTemplate.execute((RedisCallback<Long>) connection -> {
|
RedisSerializer<String> serializer = getRedisSerializer();
|
byte[] keys = serializer.serialize(key);
|
byte[] values = OBJECT_SERIALIZER.serialize(value);
|
if (keys != null && values != null) {
|
connection.set(keys, values);
|
log.debug("[redisTemplate redis]放入 缓存 url:{}", key);
|
}
|
return 1L;
|
});
|
}
|
|
/**
|
* 设置key在指定时间后过期
|
*
|
* @param key key
|
* @param time 过期时间,单位毫秒
|
*/
|
public void expire(final String key, final long time) {
|
redisTemplate.expire(key, time, TimeUnit.MILLISECONDS);
|
}
|
|
/**
|
* 查询在这个时间段内即将过期的key
|
*
|
* @param key the key
|
* @param time the time
|
* @return the list
|
*/
|
public List<String> willExpire(final String key, final long time) {
|
final List<String> keysList = new ArrayList<>();
|
redisTemplate.execute((RedisCallback<List<String>>) connection -> {
|
Set<String> keys = redisTemplate.keys(key + "*");
|
if (keys != null) {
|
for (String key1 : keys) {
|
Long ttl = connection.ttl(key1.getBytes(DEFAULT_CHARSET));
|
if (0 <= ttl && ttl <= 2 * time) {
|
keysList.add(key1);
|
}
|
}
|
}
|
return keysList;
|
});
|
return keysList;
|
}
|
|
|
/**
|
* 查询在以keyPatten的所有 key
|
*
|
* @param keyPatten the key patten
|
* @return the set
|
*/
|
public Set<String> keys(final String keyPatten) {
|
return redisTemplate.execute((RedisCallback<Set<String>>) connection -> redisTemplate.keys(keyPatten + "*"));
|
}
|
|
/**
|
* 根据key获取对象
|
*
|
* @param key the key
|
* @return the byte [ ]
|
*/
|
public byte[] get(final byte[] key) {
|
byte[] result = redisTemplate.execute((RedisCallback<byte[]>) connection -> connection.get(key));
|
log.debug("[redisTemplate redis]取出 缓存 url:{} ", key);
|
return result;
|
}
|
|
/**
|
* 根据key获取对象
|
*
|
* @param key the key
|
* @return the string
|
*/
|
public Object get(final String key) {
|
Object resultStr = redisTemplate.execute((RedisCallback<Object>) connection -> {
|
RedisSerializer<String> serializer = getRedisSerializer();
|
byte[] keys = serializer.serialize(key);
|
if (keys == null) {
|
return null;
|
}
|
byte[] values = connection.get(keys);
|
return OBJECT_SERIALIZER.deserialize(values);
|
});
|
log.debug("[redisTemplate redis]取出 缓存 url:{} ", key);
|
return resultStr;
|
}
|
|
public <T> T get(final String key, Class<T> clazz) {
|
Object resultStr = get(key);
|
log.debug("[redisTemplate redis]取出 缓存 url:{} ", key);
|
if (resultStr != null) {
|
return (T) resultStr;
|
}
|
return null;
|
}
|
|
/**
|
* 根据key获取对象
|
*
|
* @param keyPatten the key patten
|
* @return the keys values
|
*/
|
public Map<String, Object> getKeysValues(final String keyPatten) {
|
log.debug("[redisTemplate redis] getValues() patten={} ", keyPatten);
|
return redisTemplate.execute((RedisCallback<Map<String, Object>>) connection -> {
|
RedisSerializer<String> serializer = getRedisSerializer();
|
Map<String, Object> maps = new HashMap<>(16);
|
Set<String> keys = redisTemplate.keys(keyPatten + "*");
|
if (CollectionUtils.isNotEmpty(keys)) {
|
for (String key : keys) {
|
byte[] bKeys = serializer.serialize(key);
|
if (bKeys == null) {
|
return null;
|
}
|
byte[] bValues = connection.get(bKeys);
|
Object value = OBJECT_SERIALIZER.deserialize(bValues);
|
maps.put(key, value);
|
}
|
}
|
return maps;
|
});
|
}
|
|
/**
|
* Ops for hash hash operations.
|
*
|
* @return the hash operations
|
*/
|
public HashOperations<String, String, Object> opsForHash() {
|
return redisTemplate.opsForHash();
|
}
|
|
/**
|
* 对HashMap操作
|
*
|
* @param key the key
|
* @param hashKey the hash key
|
* @param hashValue the hash value
|
*/
|
public void putHashValue(String key, String hashKey, Object hashValue) {
|
log.debug("[redisTemplate redis] putHashValue() key={},hashKey={},hashValue={} ", key, hashKey, hashValue);
|
opsForHash().put(key, hashKey, hashValue);
|
}
|
|
/**
|
* 获取单个field对应的值
|
*
|
* @param key the key
|
* @param hashKey the hash key
|
* @return the hash values
|
*/
|
public Object getHashValue(String key, String hashKey) {
|
log.debug("[redisTemplate redis] getHashValues() key={},hashKey={}", key, hashKey);
|
return opsForHash().get(key, hashKey);
|
}
|
|
/**
|
* 根据key值删除
|
*
|
* @param key the key
|
* @param hashKeys the hash keys
|
*/
|
public void delHashValues(String key, Object... hashKeys) {
|
log.debug("[redisTemplate redis] delHashValues() key={}", key);
|
opsForHash().delete(key, hashKeys);
|
}
|
|
/**
|
* key只匹配map
|
*
|
* @param key the key
|
* @return the hash value
|
*/
|
public Map<String, Object> getHashValues(String key) {
|
log.debug("[redisTemplate redis] getHashValue() key={}", key);
|
return opsForHash().entries(key);
|
}
|
|
/**
|
* 批量添加
|
*
|
* @param key the key
|
* @param map the map
|
*/
|
public void putHashValues(String key, Map<String, Object> map) {
|
opsForHash().putAll(key, map);
|
}
|
|
/**
|
* 集合数量
|
*
|
* @return the long
|
*/
|
public long dbSize() {
|
Long size = redisTemplate.execute(RedisServerCommands::dbSize);
|
return Optional.ofNullable(size).orElse(0L);
|
}
|
|
/**
|
* 清空redis存储的数据
|
*
|
* @return the string
|
*/
|
public String flushDB() {
|
return redisTemplate.execute((RedisCallback<String>) connection -> {
|
connection.flushDb();
|
return "ok";
|
});
|
}
|
|
/**
|
* 判断某个主键是否存在
|
*
|
* @param key the key
|
* @return the boolean
|
*/
|
public boolean exists(final String key) {
|
Boolean exist = redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.exists(key.getBytes(DEFAULT_CHARSET)));
|
return Optional.ofNullable(exist).orElse(false);
|
}
|
|
|
/**
|
* 删除key
|
*
|
* @param keys the keys
|
* @return the long
|
*/
|
@SuppressWarnings("ConstantConditions")
|
public long del(final String... keys) {
|
return redisTemplate.execute((RedisCallback<Long>) connection -> {
|
long result = 0;
|
for (String key : keys) {
|
result = connection.del(key.getBytes(DEFAULT_CHARSET));
|
}
|
return result;
|
});
|
}
|
|
/**
|
* 获取 RedisSerializer
|
*
|
* @return the redis serializer
|
*/
|
protected RedisSerializer<String> getRedisSerializer() {
|
return redisTemplate.getStringSerializer();
|
}
|
|
/**
|
* 对某个主键对应的值加一,value值必须是全数字的字符串
|
*
|
* @param key the key
|
* @return the long
|
*/
|
@SuppressWarnings("ConstantConditions")
|
public long incr(final String key) {
|
return redisTemplate.execute((RedisCallback<Long>) connection -> {
|
RedisSerializer<String> redisSerializer = getRedisSerializer();
|
return connection.incr(redisSerializer.serialize(key));
|
});
|
}
|
|
/**
|
* redis List 引擎
|
*
|
* @return the list operations
|
*/
|
public ListOperations<String, Object> opsForList() {
|
return redisTemplate.opsForList();
|
}
|
|
/**
|
* redis List数据结构 : 将一个或多个值 value 插入到列表 key 的表头
|
*
|
* @param key the key
|
* @param value the value
|
* @return the long
|
*/
|
public Long leftPush(String key, Object value) {
|
return opsForList().leftPush(key, value);
|
}
|
|
/**
|
* redis List数据结构 : 移除并返回列表 key 的头元素
|
*
|
* @param key the key
|
* @return the string
|
*/
|
public Object leftPop(String key) {
|
return opsForList().leftPop(key);
|
}
|
|
/**
|
* redis List数据结构 :将一个或多个值 value 插入到列表 key 的表尾(最右边)。
|
*
|
* @param key the key
|
* @param value the value
|
* @return the long
|
*/
|
public Long in(String key, Object value) {
|
return opsForList().rightPush(key, value);
|
}
|
|
/**
|
* redis List数据结构 : 移除并返回列表 key 的末尾元素
|
*
|
* @param key the key
|
* @return the string
|
*/
|
public Object rightPop(String key) {
|
return opsForList().rightPop(key);
|
}
|
|
|
/**
|
* redis List数据结构 : 返回列表 key 的长度 ; 如果 key 不存在,则 key 被解释为一个空列表,返回 0 ; 如果 key 不是列表类型,返回一个错误。
|
*
|
* @param key the key
|
* @return the long
|
*/
|
public Long length(String key) {
|
return opsForList().size(key);
|
}
|
|
|
/**
|
* redis List数据结构 : 根据参数 i 的值,移除列表中与参数 value 相等的元素
|
*
|
* @param key the key
|
* @param i the
|
* @param value the value
|
*/
|
public void remove(String key, long i, Object value) {
|
opsForList().remove(key, i, value);
|
}
|
|
/**
|
* redis List数据结构 : 将列表 key 下标为 index 的元素的值设置为 value
|
*
|
* @param key the key
|
* @param index the index
|
* @param value the value
|
*/
|
public void set(String key, long index, Object value) {
|
opsForList().set(key, index, value);
|
}
|
|
/**
|
* redis List数据结构 : 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 end 指定。
|
*
|
* @param key the key
|
* @param start the start
|
* @param end the end
|
* @return the list
|
*/
|
public List<Object> getList(String key, int start, int end) {
|
return opsForList().range(key, start, end);
|
}
|
|
/**
|
* redis List数据结构 : 批量存储
|
*
|
* @param key the key
|
* @param list the list
|
* @return the long
|
*/
|
public Long leftPushAll(String key, List<String> list) {
|
return opsForList().leftPushAll(key, list);
|
}
|
|
/**
|
* redis List数据结构 : 将值 value 插入到列表 key 当中,位于值 index 之前或之后,默认之后。
|
*
|
* @param key the key
|
* @param index the index
|
* @param value the value
|
*/
|
public void insert(String key, long index, Object value) {
|
opsForList().set(key, index, value);
|
}
|
}
|