<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.0.0.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>lettuce-core</artifactId>
<groupId>io.lettuce</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.10.0</version>
</dependency>
# Redis数据库索引()
spring.redis.database=10
# Redis服务器地址
spring.redis.host=***
# Redis服务器连接密码(默认为空)
spring.redis.password=***
# Redis服务器连接端口
spring.redis.port=26379
# 连接超时时间(毫秒)
spring.redis.timeout=0
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
package com.util;/**
import lombok.Getter;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
/**
* @ClassName RedisUtil
* @Description TODO
* @Author Qhx
* @Date 2019/5/8
**/
@Component
public class RedisUtil {
//region 设置注入的redis对象
// public RedisUtil(RedisTemplate<String, Object> template) {
// stringRedisTemplate=template;
// }
@Getter
private StringRedisTemplate stringRedisTemplate;
@Resource(name = "defaultRedisTemplate")
private StringRedisTemplate defaultRedisTemplate;
@Resource(name = "cacheRedisTemplate")
private StringRedisTemplate cacheRedisTemplate;
@Resource(name ="defaultRedisFactory" )
private JedisConnectionFactory jedisConnectionFactory;
private static RedisUtil redisUtil;
/**
* @PostConstruct:被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,
* 并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
* (PreDestroy()方法在destroy()方法执行执行之后执行)
*/
@PostConstruct
public void init() {
redisUtil = this;
redisUtil.defaultRedisTemplate= this.defaultRedisTemplate;
redisUtil.cacheRedisTemplate= this.cacheRedisTemplate;
redisUtil.stringRedisTemplate = this.defaultRedisTemplate;
}
public void setDefaultRedisTemplate(){
this.stringRedisTemplate=defaultRedisTemplate;
}
public void setCacheRedisTemplate(){
this.stringRedisTemplate=cacheRedisTemplate;
}
//endregion
//region redis实例重启
public void validateObject(final Object obj) {
boolean closed = stringRedisTemplate.getConnectionFactory().getConnection().isClosed();
if (closed) {
// Jedis jedis = stringRedisTemplate.getConnectionFactory().getConnection().getNativeConnection();
RedisConnection jedisConnection = jedisConnectionFactory.getConnection();
Jedis jedis = (Jedis)jedisConnection.getNativeConnection();
}
}
//endregion
/** TODO ---------------------------------key相关操作---------------------------------------------- */
//region key相关操作
/**
* 删除key(成功返回true)
*
* @param key 不能为空
*/
public Boolean delete(String key) {
stringRedisTemplate.delete(key);
return true;
}
/**
* 批量删除key(成功返回true)
*
* @param keys
*/
public Boolean delete(Collection<String> keys) {
stringRedisTemplate.delete(keys);
return true;
}
/**
* 序列化key
*
* @param key 不能为空
* @return
*/
public byte[] dump(String key) {
return stringRedisTemplate.dump(key);
}
/**
* 是否存在key(存在返回true)
*
* @param key 不能为空
* @return
*/
public Boolean hasKey(String key) {
return stringRedisTemplate.hasKey(key);
}
/**
* 设置过期时间
*
* @param key
* @param timeout
* @param unit
* @return
*/
public Boolean expire(String key, long timeout, TimeUnit unit) {
return stringRedisTemplate.expire(key, timeout, unit);
}
/**
* 设置过期时间
*
* @param key
* @param date
* @return
*/
public Boolean expireAt(String key, Date date) {
return stringRedisTemplate.expireAt(key, date);
}
/**
* 查找匹配的key------不要用这个可以用SCAN 遍历查询所有的key,在生产环境中使用会导致,redis卡在这里
* 获取所以key
* @param pattern
* @return
*/
public Set<String> keys(String pattern) {
return stringRedisTemplate.keys(pattern);
}
public Set<String> scan(String pattern){
HashSet<String> set = new HashSet<>();
RedisConnection connection = stringRedisTemplate.getConnectionFactory().getConnection();
Cursor<byte[]> c = connection.scan(new ScanOptions.ScanOptionsBuilder().match(pattern).build());
while (c.hasNext()) {
set.add(new String(c.next()));
}
return set;
/*stringRedisTemplate.execute(new RedisCallback<Set<Object>>() {
@Override
public Set<Object> doInRedis(RedisConnection connection) throws DataAccessException {
Set<Object> binaryKeys = new HashSet<>();
Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match("*").build());
while (cursor.hasNext()) {
binaryKeys.add(new String(cursor.next()));
set.add(new String(cursor.next()));
}
return binaryKeys;
}
});
return set;*/
}
/**
* 将当前数据库的 key 移动到给定的数据库 db 当中
*
* @param key
* @param dbIndex
* @return
*/
public Boolean move(String key, int dbIndex) {
return stringRedisTemplate.move(key, dbIndex);
}
/**
* 移除 key 的过期时间,key 将持久保持
*
* @param key
* @return
*/
public Boolean persist(String key) {
return stringRedisTemplate.persist(key);
}
/**
* 返回 key 的剩余的过期时间
*
* @param key
* @param unit
* @return
*/
public Long getExpire(String key, TimeUnit unit) {
return stringRedisTemplate.getExpire(key, unit);
}
/**
* 返回 key 的剩余的过期时间
*
* @param key
* @return
*/
public Long getExpire(String key) {
return stringRedisTemplate.getExpire(key);
}
/**
* 从当前数据库中随机返回一个 key
*
* @return
*/
public String randomKey() {
return stringRedisTemplate.randomKey();
}
/**
* 修改 key 的名称
*
* @param oldKey
* @param newKey
*/
public void rename(String oldKey, String newKey) {
stringRedisTemplate.rename(oldKey, newKey);
}
/**
* 仅当 newkey 不存在时,将 oldKey 改名为 newkey
*
* @param oldKey
* @param newKey
* @return
*/
public Boolean renameIfAbsent(String oldKey, String newKey) {
return stringRedisTemplate.renameIfAbsent(oldKey, newKey);
}
/**
* 返回 key 所储存的值的类型
*
* @param key
* @return
*/
public DataType type(String key) {
return stringRedisTemplate.type(key);
}
//endregion
/** TODO ----------------------------------string相关操作------------------------------------- */
//region string相关操作
/**
* 设置指定 key 的值
* @param key
* @param value
* @param howManyDays 多少天
*/
public void setByDays( String key , String value , long howManyDays ){
stringRedisTemplate.opsForValue().set(key, value, howManyDays, TimeUnit.DAYS);
}
/**
* 设置指定 key 的值
* @param key
* @param value
* @param howManySeconds 多少秒
*/
public void setBySeconds( String key , String value , long howManySeconds ){
stringRedisTemplate.opsForValue().set(key, value, howManySeconds, TimeUnit.SECONDS);
}
/**
* 设置指定 key 的值
* @param key
* @param value
*/
public void set(String key, String value) {
stringRedisTemplate.opsForValue().set(key, value);
}
/**
* 获取指定 key 的值
* @param key
* @return
*/
public String get(String key) {
String val = stringRedisTemplate.opsForValue().get(key);
if (val == null) {
return null;
} else {
return stringRedisTemplate.opsForValue().get(key).toString();
}
}
/**
* 返回 key 中字符串值的子字符(从0开始算)
* @param key
* @param start
* @param end
* @return
*/
public String getRange(String key, long start, long end) {
return stringRedisTemplate.opsForValue().get(key, start, end);
}
/**
* 将给定 key 的值设为 value ,并返回 key 的旧值(old value)
*
* @param key
* @param value
* @return
*/
public String getAndSet(String key, String value) {
return stringRedisTemplate.opsForValue().getAndSet(key, value).toString();
}
/**
* 对 key 所储存的字符串值,获取指定偏移量上的位(bit)
*
* @param key
* @param offset
* @return
*/
public Boolean getBit(String key, long offset) {
return stringRedisTemplate.opsForValue().getBit(key, offset);
}
/**
* 批量获取
*
* @param keys
* @return
*/
public List<String> multiGet(Collection<String> keys) {
return stringRedisTemplate.opsForValue().multiGet(keys);
}
/**
* 设置ASCII码, 字符串'a'的ASCII码是97, 转为二进制是'01100001', 此方法是将二进制第offset位值变为value
*
* @param key
* @ postion
* 位置
* @param value
* 值,true为1, false为0
* @return
*/
public boolean setBit(String key, long offset, boolean value) {
return stringRedisTemplate.opsForValue().setBit(key, offset, value);
}
/**
* 将值 value 关联到 key ,并将 key 的过期时间设为 timeout
*
* @param key
* @param value
* @param timeout
* 过期时间
* @param unit
* 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES
* 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
*/
public void setEx(String key, String value, long timeout, TimeUnit unit) {
stringRedisTemplate.opsForValue().set(key, value, timeout, unit);
}
/**
* 只有在 key 不存在时设置 key 的值
* key唯一 如果key不存在 就返回false 并且无法插入
* @param key
* @param value
* @return 之前已经存在返回false,不存在返回true
*/
public boolean setIfAbsent(String key, String value) {
return stringRedisTemplate.opsForValue().setIfAbsent(key, value);
}
/**
* 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始
* 替换key对应的String从offset位置开始的后面字段成value,如果不够就替换部分
* 该方法是用 value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始
* @param key
* @param value
* @param offset
* 从指定位置开始覆写
*/
public void setRange(String key, String value, long offset) {
stringRedisTemplate.opsForValue().set(key, value, offset);
}
/**
* 获取字符串的长度
*
* @param key
* @return
*/
public Long size(String key) {
return stringRedisTemplate.opsForValue().size(key);
}
/**
* 批量添加
*
* @param maps
*/
public void multiSet(Map<String, String> maps) {
stringRedisTemplate.opsForValue().multiSet(maps);
}
/**
* 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在
*
* @param maps
* @return 之前已经存在返回false,不存在返回true
*/
public boolean multiSetIfAbsent(Map<String, String> maps) {
return stringRedisTemplate.opsForValue().multiSetIfAbsent(maps);
}
/**
* 正数为增加, 负数则为减多少,不写是(自增长)
*
* @param key
* @ value
* @return
*/
public Long incrBy(String key, long increment) {
return stringRedisTemplate.opsForValue().increment(key, increment);
}
/**
* 正数为增加, 负数则为减多少
* @param key
* @ value
* @return
*/
public Double incrByFloat(String key, double increment) {
return stringRedisTemplate.opsForValue().increment(key, increment);
}
/**
* 追加到末尾
*
* @param key
* @param value
* @return
*/
public Integer append(String key, String value) {
return stringRedisTemplate.opsForValue().append(key, value);
}
//endregion
/** TODO ---------------------------------------hash相关操作-------------------------------------------- */
//region hash相关操作
/**
* 获取存储在哈希表中指定字段的值
*
* @param key
* @param field
* @return
*/
public Object hGet(String key, String field) {
return stringRedisTemplate.opsForHash().get(key, field);
}
/**
* 获取所有给定字段的值
*
* @param key
* @return {key2=b, key1=a, key3=c}获取hsah内容
*/
public Map<Object, Object> hGetAll(String key) {
return stringRedisTemplate.opsForHash().entries(key);
}
/**
* 获取所有给定字段的值
*
* @param key
* @param fields
* @return
*/
public List<Object> hMultiGet(String key, Collection<Object> fields) {
return stringRedisTemplate.opsForHash().multiGet(key, fields);
}
/**
* 为散列添加或者覆盖一个 key-value键值对
*/
public void hPut(String key, String hashKey, String value) {
stringRedisTemplate.opsForHash().put(key, hashKey, value);
}
/**
* 为散列添加多个key-value键值对
*
* @ key must not be {@literal null}.
* @ m must not be {@literal null}.
*/
public void hPutAll(String key, Map<String, String> maps) {
stringRedisTemplate.opsForHash().putAll(key, maps);
}
/**
* 仅当hashKey不存在时才设置
* 为散列添加一个key-value键值对。如果存在则不添加不覆盖。返回false
*
* @param key
* @param hashKey
* @param value
* @return
*/
public Boolean hPutIfAbsent(String key, String hashKey, String value) {
return stringRedisTemplate.opsForHash().putIfAbsent(key, hashKey, value);
}
/**
* 删除一个或多个哈希表字段
*
* @param key 不能为null 散列的名称
* @param fields 需要删除的keys集合
* @return
*/
public Long hDelete(String key, Object... fields) {
return stringRedisTemplate.opsForHash().delete(key, fields);
}
/**
* 查看哈希表 key 中,指定的字段是否存在
*
* @param key
* @param field
* @return
*/
public boolean hExists(String key, String field) {
return stringRedisTemplate.opsForHash().hasKey(key, field);
}
/**
* 为哈希表 key 中的指定字段的整数值加上增量 increment
*
* @param key
* @param field
* @param increment
* @return
*/
public Long hIncrBy(String key, Object field, long increment) {
return stringRedisTemplate.opsForHash().increment(key, field, increment);
}
/**
* 为哈希表 key 中的指定字段的整数值加上增量 increment
*
* @param key
* @param field
* @param delta
* @return
*/
public Double hIncrByFloat(String key, Object field, double delta) {
return stringRedisTemplate.opsForHash().increment(key, field, delta);
}
/**
* 获取所有哈希表中的字段
*
* @param key
* @return
*/
public Set<Object> hKeys(String key) {
return stringRedisTemplate.opsForHash().keys(key);
}
/**
* 获取哈希表中字段的数量
*
* @param key
* @return
*/
public Long hSize(String key) {
return stringRedisTemplate.opsForHash().size(key);
}
/**
* 获取哈希表中所有值
*
* @param key
* @return
*/
public List<Object> hValues(String key) {
return stringRedisTemplate.opsForHash().values(key);
}
/**
* 迭代哈希表中的键值对
*
* @param key
* @param options
* @return
*/
public Cursor<Entry<Object, Object>> hScan(String key, ScanOptions options) {
return stringRedisTemplate.opsForHash().scan(key, options);
}
//endregion
/** TODO ---------------------------------list相关操作---------------------------------------- */
//region list相关操作
/**
* 通过索引获取列表中的元素
* 当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误。
* @param key
* @param index
* @return
*/
public String lIndex(String key, long index) {
return stringRedisTemplate.opsForList().index(key, index).toString();
}
/**
* 获取列表指定范围内的元素
* 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。
* 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
* @param key
* @param start
* 开始位置, 0是开始位置
* @param end
* 结束位置, -1返回所有
* @return
*/
public List<String> lRange(String key, long start, long end) {
return stringRedisTemplate.opsForList().range(key, start, end);
}
/**
* 存储在list头部
* left 是左面进入 也就是靠前 先进后出 返回的是list的数量从1开始
* @param key
* @param value
* @return
*/
public Long lLeftPush(String key, String value) {
return stringRedisTemplate.opsForList().leftPush(key, value);
}
/**
* 将数组倒过来添加进去
* @param key
* @param value
* @return
*/
public Long lLeftPushAll(String key, String... value) {
return stringRedisTemplate.opsForList().leftPushAll(key, value);
}
/**
* 将集合倒过来添加进去
* @param key
* @param value
* @return
*/
public Long lLeftPushAll(String key, Collection<String> value) {
return stringRedisTemplate.opsForList().leftPushAll(key, value);
}
/**
* 当list存在的时候才加入
* 把值加入列表的头部 必须有一个值。没有值无效
* @param key
* @param value
* @return
*/
public Long lLeftPushIfPresent(String key, String value) {
return stringRedisTemplate.opsForList().leftPushIfPresent(key, value);
}
/**
* 如果pivot存在,再pivot前面添加
* 把值插入到指定元素的前面
* 输入 0 1 50 然后把 2插入到0前面 就是 50 1 2 0
* @param key
* @param pivot
* @param value
* @return
*/
public Long lLeftPush(String key, String pivot, String value) {
return stringRedisTemplate.opsForList().leftPush(key, pivot, value);
}
/**
* 按顺序添加
* @param key
* @param value
* @return
*/
public Long lRightPush(String key, String value) {
return stringRedisTemplate.opsForList().rightPush(key, value);
}
/**
* 按顺序添加数组
* @param key
* @param value
* @return
*/
public Long lRightPushAll(String key, String... value) {
return stringRedisTemplate.opsForList().rightPushAll(key, value);
}
/**
* 按顺序添加集合
* @param key
* @param value
* @return
*/
public Long lRightPushAll(String key, Collection<String> value) {
return stringRedisTemplate.opsForList().rightPushAll(key, value);
}
/**
* 为已存在的列表添加值
* 必须有一个key 否则无效 然后存在之后继续向后插值
* @param key
* @param value
* @return
*/
public Long lRightPushIfPresent(String key, String value) {
return stringRedisTemplate.opsForList().rightPushIfPresent(key, value);
}
/**
* 在pivot元素的右边添加值
* 指定Value后面插入值
* @param key
* @param pivot
* @param value
* @return
*/
public Long lRightPush(String key, String pivot, String value) {
return stringRedisTemplate.opsForList().rightPush(key, pivot, value);
}
/**
* 通过索引设置列表元素的值
* 当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误。
* @param key
* @param index
* 位置
* @param value
*/
public void lSet(String key, long index, String value) {
stringRedisTemplate.opsForList().set(key, index, value);
}
/**
* 移出并获取列表的第一个元素
*
* @param key
* @return 删除的元素
*/
public String lLeftPop(String key) {
return stringRedisTemplate.opsForList().leftPop(key).toString();
}
/**
* 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
*
* @param key
* @param timeout
* 等待时间
* @param unit
* 时间单位
* @return
*/
public String lBLeftPop(String key, long timeout, TimeUnit unit) {
return stringRedisTemplate.opsForList().leftPop(key, timeout, unit).toString();
}
/**
* 移除并获取列表最后一个元素
*
* @param key
* @return 删除的元素
*/
public String lRightPop(String key) {
return stringRedisTemplate.opsForList().rightPop(key).toString();
}
/**
* 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
*
* @param key
* @param timeout
* 等待时间
* @param unit
* 时间单位
* @return
*/
public String lBRightPop(String key, long timeout, TimeUnit unit) {
return stringRedisTemplate.opsForList().rightPop(key, timeout, unit).toString();
}
/**
* 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
*
* @param sourceKey
* @param destinationKey
* @return
*/
public String lRightPopAndLeftPush(String sourceKey, String destinationKey) {
return stringRedisTemplate.opsForList().rightPopAndLeftPush(sourceKey,
destinationKey).toString();
}
/**
* 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
*
* @param sourceKey
* @param destinationKey
* @param timeout
* @param unit
* @return
*/
public String lBRightPopAndLeftPush(String sourceKey, String destinationKey,
long timeout, TimeUnit unit) {
return stringRedisTemplate.opsForList().rightPopAndLeftPush(sourceKey,
destinationKey, timeout, unit).toString();
}
/**
* 删除集合中值等于value得元素
*
* @param key
* @param index
* index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素;
* index<0, 从尾部开始删除第一个值等于value的元素;
* @param value
* @return
*/
public Long lRemove(String key, long index, String value) {
return stringRedisTemplate.opsForList().remove(key, index, value);
}
/**
* 裁剪list
*
* @param key
* @param start
* @param end
*/
public void lTrim(String key, long start, long end) {
stringRedisTemplate.opsForList().trim(key, start, end);
}
/**
* 获取列表长度
*
* @param key
* @return
*/
public Long lSize(String key) {
return stringRedisTemplate.opsForList().size(key);
}
//endregion
/** TODO ------------------------------------------set相关操作--------------------------------------------------------- */
//region set相关操作
/**
* set添加元素
*
* @param key
* @param values
* @return
*/
public Long sAdd(String key, String... values) {
return stringRedisTemplate.opsForSet().add(key, values);
}
/*//循环填充数组的方法 wbh 2019-5-17
public Long sAdd(String key, List<Integer> list) {
if (list != null && list.size() > 0) {
Integer[] values = new Integer[list.size()];
;
for (int i = 0; i < list.size(); i++) {
values[i] = list.get(0);
}
return stringRedisTemplate.opsForSet().add(key, values);
}
return 0L;
}
//递归的方法 wbh 2019-5-17
public Long sAdd2(String key, List<Integer> list, Integer... values ) {
if (list != null && list.size() > 0) {
Integer value = list.get(0);
list.remove(0);
int length=values.length;
Integer[] values2=new Integer[length+1];;
System.arraycopy(values,0, values2,0,length);
values2[length]=value;
return sAdd2(key, list, values2);
} else {
return stringRedisTemplate.opsForSet().add(key, values);
}
}*/
/**
* 向redis的Set数据类型中添加集合对象
* @param key
* @param list
* @param values
* @return
*/
public Long sAddCollection(String key, Collection<? extends String> list, String... values ) {
if (list != null && list.size() > 0) {
values=list.toArray(new String[list.size()]);
return stringRedisTemplate.opsForSet().add(key,values);
}
return 0L;
}
/**
* set移除元素
*
* @param key
* @param values
* @return
*/
public Long sRemove(String key, Object... values) {
return stringRedisTemplate.opsForSet().remove(key, values);
}
/**
* 移除并返回集合的一个随机元素
*
* @param key
* @return
*/
public String sPop(String key) {
return stringRedisTemplate.opsForSet().pop(key).toString();
}
/**
* 将元素value从一个集合移到另一个集合
*
* @param key
* @param value
* @param destKey
* @return
*/
public Boolean sMove(String key, String value, String destKey) {
return stringRedisTemplate.opsForSet().move(key, value, destKey);
}
/**
* 获取集合的大小
*
* @param key
* @return
*/
public Long sSize(String key) {
return stringRedisTemplate.opsForSet().size(key);
}
/**
* 判断集合是否包含value
*
* @param key
* @param value
* @return
*/
public Boolean sIsMember(String key, Object value) {
return stringRedisTemplate.opsForSet().isMember(key, value);
}
/**
* 获取两个集合的交集
*
* @param key
* @param otherKey
* @return
*/
public Set<String> sIntersect(String key, String otherKey) {
return stringRedisTemplate.opsForSet().intersect(key, otherKey);
}
/**
* 获取key集合与多个集合的交集
*
* @param key
* @param otherKeys
* @return
*/
public Set<String> sIntersect(String key, Collection<String> otherKeys) {
return stringRedisTemplate.opsForSet().intersect(key, otherKeys);
}
/**
* key集合与otherKey集合的交集存储到destKey集合中
*
* @param key
* @param otherKey
* @param destKey
* @return
*/
public Long sIntersectAndStore(String key, String otherKey, String destKey) {
return stringRedisTemplate.opsForSet().intersectAndStore(key, otherKey,
destKey);
}
/**
* key集合与多个集合的交集存储到destKey集合中
*
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long sIntersectAndStore(String key, Collection<String> otherKeys,
String destKey) {
return stringRedisTemplate.opsForSet().intersectAndStore(key, otherKeys,
destKey);
}
/**
* 获取两个集合的并集
*
* @param key
* @param otherKeys
* @return
*/
public Set<String> sUnion(String key, String otherKeys) {
return stringRedisTemplate.opsForSet().union(key, otherKeys);
}
/**
* 获取key集合与多个集合的并集
*
* @param key
* @param otherKeys
* @return
*/
public Set<String> sUnion(String key, Collection<String> otherKeys) {
return stringRedisTemplate.opsForSet().union(key, otherKeys);
}
/**
* key集合与otherKey集合的并集存储到destKey中
*
* @param key
* @param otherKey
* @param destKey
* @return
*/
public Long sUnionAndStore(String key, String otherKey, String destKey) {
return stringRedisTemplate.opsForSet().unionAndStore(key, otherKey, destKey);
}
/**
* key集合与多个集合的并集存储到destKey中
*
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long sUnionAndStore(String key, Collection<String> otherKeys,
String destKey) {
return stringRedisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey);
}
/**
* 获取两个集合的差集
*
* @param key
* @param otherKey
* @return
*/
public Set<String> sDifference(String key, String otherKey) {
return stringRedisTemplate.opsForSet().difference(key, otherKey);
}
/**
* 获取key集合与多个集合的差集
*
* @param key
* @param otherKeys
* @return
*/
public Set<String> sDifference(String key, Collection<String> otherKeys) {
return stringRedisTemplate.opsForSet().difference(key, otherKeys);
}
/**
* key集合与otherKey集合的差集存储到destKey中
*
* @param key
* @param otherKey
* @param destKey
* @return
*/
public Long sDifference(String key, String otherKey, String destKey) {
return stringRedisTemplate.opsForSet().differenceAndStore(key, otherKey,
destKey);
}
/**
* key集合与多个集合的差集存储到destKey中
*
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long sDifference(String key, Collection<String> otherKeys,
String destKey) {
return stringRedisTemplate.opsForSet().differenceAndStore(key, otherKeys,
destKey);
}
/**
* 获取集合所有元素
*
* @param key
* @ otherKeys
* @ destKey
* @return
*/
public Set<String> setMembers(String key) {
return stringRedisTemplate.opsForSet().members(key);
}
/**
* 随机获取集合中的一个元素
*
* @param key
* @return
*/
public String sRandomMember(String key) {
return stringRedisTemplate.opsForSet().randomMember(key).toString();
}
/**
* 随机获取集合中count个元素
*
* @param key
* @param count
* @return
*/
public List<String> sRandomMembers(String key, long count) {
return stringRedisTemplate.opsForSet().randomMembers(key, count);
}
/**
* 随机获取集合中count个元素并且去除重复的
*
* @param key
* @param count
* @return
*/
public Set<String> sDistinctRandomMembers(String key, long count) {
return stringRedisTemplate.opsForSet().distinctRandomMembers(key, count);
}
/**
* 遍历
* @param key
* @param options
* @return
*/
public Cursor<String> sScan(String key, ScanOptions options) {
return stringRedisTemplate.opsForSet().scan(key, options);
}
//endregion
/** TODO ----------------------------------zSet相关操作-------------------------------------------------*/
//region zSet相关操作
/**
* 添加元素,有序集合是按照元素的score值由小到大排列
*
* @param key
* @param value
* @param score
* @return
*/
public Boolean zAdd(String key, String value, double score) {
return stringRedisTemplate.opsForZSet().add(key, value, score);
}
/**
* 添加set对象
* @param key
* @param values
* @return
*/
public Long zAdd(String key, Set<TypedTuple<String>> values) {
return stringRedisTemplate.opsForZSet().add(key, values);
}
/**
* 移除有序集合中指定的多个成员. 如果成员不存在则忽略
* @param key
* @param values
* @return
*/
public Long zRemove(String key, Object... values) {
return stringRedisTemplate.opsForZSet().remove(key, values);
}
/**
* 增加元素的score值,并返回增加后的值
*
* @param key
* @param value
* @param delta
* @return
*/
public Double zIncrementScore(String key, String value, double delta) {
return stringRedisTemplate.opsForZSet().incrementScore(key, value, delta);
}
/**
* 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
*
* @param key
* @param value
* @return 0表示第一位
*/
public Long zRank(String key, Object value) {
return stringRedisTemplate.opsForZSet().rank(key, value);
}
/**
* 返回元素在集合的排名,按元素的score值由大到小排列
*
* @param key
* @param value
* @return
*/
public Long zReverseRank(String key, Object value) {
return stringRedisTemplate.opsForZSet().reverseRank(key, value);
}
/**
* 获取集合的元素, 从小到大排序
*
* @param key
* @param start
* 开始位置
* @param end
* 结束位置, -1查询所有
* @return
*/
public Set<String> zRange(String key, long start, long end) {
return stringRedisTemplate.opsForZSet().range(key, start, end);
}
/**
* 获取集合元素, 并且把score值也获取
*
* @param key
* @param start
* @param end
* @return
*/
public Set<TypedTuple<String>> zRangeWithScores(String key, long start, long end) {
return stringRedisTemplate.opsForZSet().rangeWithScores(key, start, end);
}
/**
* 根据Score值查询集合元素
*
* @param key
* @param min
* 最小值
* @param max
* 最大值
* @return
*/
public Set<String> zRangeByScore(String key, double min, double max) {
return stringRedisTemplate.opsForZSet().rangeByScore(key, min, max);
}
/**
* 根据Score值查询集合元素, 从小到大排序
*
* @param key
* @param min
* 最小值
* @param max
* 最大值
* @return
*/
public Set<TypedTuple<String>> zRangeByScoreWithScores(String key,
double min, double max) {
return stringRedisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
}
/**
* 获取有序集合中分数在指定的最小值 与最大值之间的所有成员的TypedTuple集合 闭合区间
* 通过分数返回有序集合指定区间内的成员对象,并在索引范围内,其中有序集成员按分数值递增(从小到大)顺序排列
* 从开始到结束的范围内获取一组元组,其中分数在分类集中的最小值和最大值之间。
* @param key
* @param min
* @param max
* @param start
* @param end
* @return
*/
public Set<TypedTuple<String>> zRangeByScoreWithScores(String key,
double min, double max, long start, long end) {
return stringRedisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max,
start, end);
}
/**
* 获取集合的元素, 从大到小排序
*
* @param key
* @param start
* @param end
* @return
*/
public Set<String> zReverseRange(String key, long start, long end) {
return stringRedisTemplate.opsForZSet().reverseRange(key, start, end);
}
/**
* 获取集合的元素, 从大到小排序, 并返回score值
*
* @param key
* @param start
* @param end
* @return
*/
public Set<TypedTuple<String>> zReverseRangeWithScores(String key,
long start, long end) {
return stringRedisTemplate.opsForZSet().reverseRangeWithScores(key, start,
end);
}
/**
* 根据Score值查询集合元素, 从大到小排序
*
* @param key
* @param min
* @param max
* @return
*/
public Set<String> zReverseRangeByScore(String key, double min,
double max) {
return stringRedisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
}
/**
* 根据Score值查询集合元素, 从大到小排序
*
* @param key
* @param min
* @param max
* @return
*/
public Set<TypedTuple<String>> zReverseRangeByScoreWithScores(
String key, double min, double max) {
return stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(key,
min, max);
}
/**
* 从有序集合中获取分数在指定范围内从高到低的成员集合
* @param key
* @param min
* @param max
* @param start
* @param end
* @return
*/
public Set<String> zReverseRangeByScore(String key, double min,
double max, long start, long end) {
return stringRedisTemplate.opsForZSet().reverseRangeByScore(key, min, max,
start, end);
}
/**
* 根据score值获取集合元素数量
*
* @param key
* @param min
* @param max
* @return
*/
public Long zCount(String key, double min, double max) {
return stringRedisTemplate.opsForZSet().count(key, min, max);
}
/**
* 获取集合大小
*
* @param key
* @return
*/
public Long zSize(String key) {
return stringRedisTemplate.opsForZSet().size(key);
}
/**
* 获取集合大小
*
* @param key
* @return
*/
public Long zZCard(String key) {
return stringRedisTemplate.opsForZSet().zCard(key);
}
/**
* 获取集合中value元素的score值
*
* @param key
* @param value
* @return
*/
public Double zScore(String key, Object value) {
Double score = stringRedisTemplate.opsForZSet().score(key, value);
return score;
}
/**
* 移除指定索引位置的成员
*
* @param key
* @param start
* @param end
* @return
*/
public Long zRemoveRange(String key, long start, long end) {
return stringRedisTemplate.opsForZSet().removeRange(key, start, end);
}
/**
* 根据指定的score值的范围来移除成员
*
* @param key
* @param min
* @param max
* @return
*/
public Long zRemoveRangeByScore(String key, double min, double max) {
return stringRedisTemplate.opsForZSet().removeRangeByScore(key, min, max);
}
/**
* 获取key和otherKey的并集并存储在destKey中
*
* @param key
* @param otherKey
* @param destKey
* @return
*/
public Long zUnionAndStore(String key, String otherKey, String destKey) {
return stringRedisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey);
}
/**
* 求两个有序集合的并集,并存到目标集合中。 如果存在相同的成员,则分数相加。
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long zUnionAndStore(String key, Collection<String> otherKeys,
String destKey) {
return stringRedisTemplate.opsForZSet()
.unionAndStore(key, otherKeys, destKey);
}
/**
* 交集
* 一个有序集合与多个有序集合进行相同成员并集, 如果存在不相同相同成员,则忽略
* @param key 不能为null
* @param otherKey 不能为null
* @param destKey 不能为null
* @return 有交集时为正数,没有时为0
*/
public Long zIntersectAndStore(String key, String otherKey,
String destKey) {
return stringRedisTemplate.opsForZSet().intersectAndStore(key, otherKey,
destKey);
}
/**
* 求两个有序集合中相同成员的并集(分数相加),并存到目标集合中。没有共同的成员则忽略
* (交集)
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long zIntersectAndStore(String key, Collection<String> otherKeys,
String destKey) {
return stringRedisTemplate.opsForZSet().intersectAndStore(key, otherKeys,
destKey);
}
/**
* 遍历
* @param key
* @param options
* @return
*/
public Cursor<TypedTuple<String>> zScan(String key, ScanOptions options) {
return stringRedisTemplate.opsForZSet().scan(key, options);
}
//endregion
//TODO------------------------------------------排序(正序、倒序)--------------------------------------------
//region 排序(正序、倒序)
/**
* ZSet对象根据传入key值和参数获取对应分页排序的数据----优化方向可以应用rangeByScoreWithScores和reverseRangeByScoreWithScores直接进行分页
* @param key
* @param sortDirection 排序方法:true为正序即从小到大;false为倒序即为从大到小(排序的关键是根据分数进行排序)
* @param paging 是否分页
* @param currentPage 当前页面(即获取第几页的数据)
* @param pageNum 每页显示数据量
* @return
*/
public List<Object> pageAndSort(String key, Boolean sortDirection, Boolean paging , Integer currentPage, Integer pageNum) {
List<Object> list = new ArrayList<>();
currentPage = currentPage==null?0:currentPage-1;
pageNum = pageNum==null?3:pageNum;
sortDirection = sortDirection==null?true:sortDirection;
paging = paging==null?false:paging;
//根据分数内容进行正序或倒叙的List获取
if (sortDirection){
// LinkedHashSet<Object> set = (LinkedHashSet<Object>)stringRedisTemplate.opsForZSet().range(key, 0, -1);
Set<ZSetOperations.TypedTuple<String>> tuples = stringRedisTemplate.opsForZSet().rangeByScoreWithScores(key,0, 1000000, currentPage * pageNum, pageNum);
List<Object> list_1 = new ArrayList<>(tuples);
for (ZSetOperations.TypedTuple<String> tup:tuples) {
list_1.add(tup.getValue());
}
list.addAll(list_1);
// stringRedisTemplate.opsForList().rightPushAll(tempListKey,list_1);
}else {
// LinkedHashSet<Object> tuples = (LinkedHashSet<Object>)stringRedisTemplate.opsForZSet().reverseRange(key, 0, -1);
Set<ZSetOperations.TypedTuple<String>> tuples = stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(key,0, 1000000, currentPage * pageNum, pageNum);
List<Object> list_2 = new ArrayList<>();
for (ZSetOperations.TypedTuple<String> tup:tuples) {
list_2.add(tup.getValue());
}
list.addAll(list_2);
// stringRedisTemplate.opsForList().rightPushAll(tempListKey,list_2);
}
// list = stringRedisTemplate.opsForList().range(tempListKey,0,-1);
//如果是进行分页排序
// if (paging){
// list = stringRedisTemplate.opsForList().range(tempListKey, currentPage * pageNum, (currentPage + 1) * pageNum-1);
// }
// stringRedisTemplate.delete(tempListKey);
return list;
}
//endregion
//TODO--------------------------------------------ZSet日常----------------------------------------------
//region ZSet日常
/**
* 日常 ------ZSet
* 交集方法
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Set<String> dailyIntersectAndStore(String key, Collection<String> otherKeys,
String destKey) {
stringRedisTemplate.opsForZSet().intersectAndStore(key, otherKeys, destKey);
return stringRedisTemplate.opsForZSet().range(destKey,0,-1);
}
/**
* 日常 Set ------ZSet
* 并集方法
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Set<String> dailyUnionAndStore(String key, Collection<String> otherKeys, String destKey) {
stringRedisTemplate.opsForZSet().unionAndStore(key, otherKeys, destKey);
return stringRedisTemplate.opsForZSet().range(destKey,0,-1);
}
/**
* 日常 Set ------ZSet
* 差集方法
* @param key
* @param otherKeys
* @param destKey
* @return 返回的值为key中有,otherKeys中没有的value
*/
public Set<String> dailyDifference(String key, Collection<String> otherKeys, String destKey) {
stringRedisTemplate.delete("Temp:ZSet:diTemp1");
stringRedisTemplate.delete("Temp:ZSet");
ArrayList<String> list = new ArrayList<>();
Set<String> diTemp1Set = dailyIntersectAndStore(key, list, "Temp:ZSet:diTemp1");
for (int i = 0;i<=otherKeys.size();i++){
stringRedisTemplate.opsForZSet().remove("Temp:ZSet:diTemp1",stringRedisTemplate.opsForZSet().range(otherKeys.toArray()[i].toString(),0,-1).toArray());
}
stringRedisTemplate.opsForZSet().unionAndStore("Temp:ZSet:diTemp1","Temp:ZSet",destKey);
return stringRedisTemplate.opsForZSet().range(destKey,0,-1);
}
//endregion
}
package com.winshang.config;/**
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
@EnableCaching
public class CacheRedisConfig extends RedisConfig {
@Value("${spring.redis.database}")
private int dbIndex;
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
/**
* 配置redis连接工厂
*
* @return
*/
@Primary
@Bean(name ="cacheRedisFactory" )
public RedisConnectionFactory cacheRedisConnectionFactory() {
return createJedisConnectionFactory(dbIndex, host, port, password, timeout);
}
/**
* 配置redisTemplate 注入方式使用@Resource(name="") 方式注入
*
* @return
*/
@Bean(name = "cacheRedisTemplate")
public StringRedisTemplate cacheRedisTemplate() {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(cacheRedisConnectionFactory());
setSerializer(stringRedisTemplate);
stringRedisTemplate.afterPropertiesSet();
return stringRedisTemplate;
}
}
package com.winshang.config;/**
* Created by Qhx on 2019/5/16.
*/
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* @ClassName DefaultRedisConfig
* @Description TODO
* @Author Qhx
* @Date 2019/5/16
**/
@Configuration
@EnableCaching
public class DefaultRedisConfig extends RedisConfig {
@Value("${spring.redis.database}")
private int dbIndex;
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
/**
* 配置redis连接工厂
*
* @return
*/
@Bean(name ="defaultRedisFactory" )
public JedisConnectionFactory defaultRedisConnectionFactory() {
return createJedisConnectionFactory(dbIndex, host, port, password, timeout);
}
/**
* 配置redisTemplate 注入方式使用@Resource(name="") 方式注入
*
* @return
*/
@Bean(name = "defaultRedisTemplate")
public StringRedisTemplate defaultRedisTemplate() {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(defaultRedisConnectionFactory());
setSerializer(stringRedisTemplate);
stringRedisTemplate.afterPropertiesSet();
return stringRedisTemplate;
}
}
package com.winshang.config;/**
* Created by Qhx on 2019/5/16.
*/
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.lang.reflect.Method;
/**
* @ClassName RedisConfig
* @Description TODO
* @Author Qhx
* @Date 2019/5/16
**/
@EnableCaching
@Configuration
public class RedisConfig {
@Value("${spring.redis.pool.max-active}")
private int redisPoolMaxActive;
@Value("${spring.redis.pool.max-wait}")
private int redisPoolMaxWait;
@Value("${spring.redis.pool.max-idle}")
private int redisPoolMaxIdle;
@Value("${spring.redis.pool.min-idle}")
private int redisPoolMinIdle;
/**
* 配置Key的生成方式
*
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(o.getClass().getName())
.append(method.getName());
for (Object object : objects) {
stringBuilder.append(object.toString());
}
return stringBuilder.toString();
}
};
}
/**
* 创建redis连接工厂
*
* @param dbIndex
* @param host
* @param port
* @param password
* @param timeout
* @return
*/
public JedisConnectionFactory createJedisConnectionFactory(int dbIndex, String host, int port, String password, int timeout) {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setDatabase(dbIndex);
jedisConnectionFactory.setHostName(host);
jedisConnectionFactory.setPort(port);
jedisConnectionFactory.setPassword(password);
jedisConnectionFactory.setTimeout(timeout);
jedisConnectionFactory.setPoolConfig(setPoolConfig(redisPoolMaxIdle, redisPoolMinIdle, redisPoolMaxActive, redisPoolMaxWait, true));
return jedisConnectionFactory;
}
/**
* 配置CacheManager
*
* @param stringRedisTemplate
* @return
*/
// @Bean
// public CacheManager cacheManager(StringRedisTemplate stringRedisTemplate) {
// RedisCacheManager redisCacheManager = new RedisCacheManager(stringRedisTemplate);
// return redisCacheManager;
// }
/**
* 设置连接池属性
*
* @param maxIdle
* @param minIdle
* @param maxActive
* @param maxWait
* @param testOnBorrow
* @return
*/
public JedisPoolConfig setPoolConfig(int maxIdle, int minIdle, int maxActive, int maxWait, boolean testOnBorrow) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMinIdle(minIdle);
poolConfig.setMaxTotal(maxActive);
poolConfig.setMaxWaitMillis(maxWait);
poolConfig.setTestOnBorrow(testOnBorrow);
return poolConfig;
}
/**
* 设置RedisTemplate的序列化方式
*
* @param stringRedisTemplate
*/
public void setSerializer(StringRedisTemplate stringRedisTemplate) {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//设置键(key)的序列化方式
stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
//设置值(value)的序列化方式
stringRedisTemplate.setValueSerializer(new StringRedisSerializer());
stringRedisTemplate.setHashKeySerializer(new StringRedisSerializer());
stringRedisTemplate.setHashValueSerializer(new StringRedisSerializer());
stringRedisTemplate.afterPropertiesSet();
}
}