Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.open.capacity.redis.util.RedisUtil Maven / Gradle / Ivy
package com.open.capacity.redis.util;
import java.util.*;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.TimeoutUtils;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
/**
* @author 作者 owen
* @version 创建时间:2017年04月23日 下午20:01:06 类说明
* redis工具类
*/
@Slf4j
@SuppressWarnings("all")
public class RedisUtil {
private StringRedisTemplate stringRedisTemplate;
private HashOperations hashOperations;
private RedisConnectionFactory redisConnectionFactory;
/*
* json序列化方式
*/
private static GenericJackson2JsonRedisSerializer redisObjectSerializer = new GenericJackson2JsonRedisSerializer();
/*
* 默认RedisObjectSerializer序列化
*/
private RedisTemplate redisTemplate;
/*
* redis工具类
*
* @param redisTemplate
* @param stringRedisTemplate
* @param hashOperations
*/
public RedisUtil(LettuceConnectionFactory lettuceConnectionFactory, StringRedisTemplate stringRedisTemplate,
HashOperations hashOperations) {
this.redisConnectionFactory = redisConnectionFactory;
this.stringRedisTemplate = stringRedisTemplate;
this.hashOperations = hashOperations;
RedisTemplate redisTemplate = new RedisTemplate();
RedisSerializer stringSerializer = new StringRedisSerializer();
RedisSerializer redisObjectSerializer = new GenericJackson2JsonRedisSerializer();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer()); // key的序列化类型
redisTemplate.setValueSerializer(redisObjectSerializer); // value的序列化类型
redisTemplate.setHashKeySerializer(stringSerializer);
redisTemplate.setHashValueSerializer(redisObjectSerializer);
redisTemplate.afterPropertiesSet();
this.redisTemplate = redisTemplate ;
}
/*
* 获取消息
*
* @param topicGroup
* @param channel
* @return
*/
public String getMsg(String topicGroup, String channel) {
return hashOperations.get(topicGroup, channel);
}
/*
* 删除消息
*
* @param topicGroup
* @param channel
* @return
*/
public boolean removeMsg(String topicGroup, String channel) {
publishMsg(topicGroup, channel, StringUtils.EMPTY);
return hashOperations.delete(topicGroup, channel) == 1;
}
/*
* 发送消息,存redis hash
*
* @param topicGroup
* @param channel
* @param msg
* @return
*/
public boolean publishMsg(String topicGroup, String channel, String msg) {
hashOperations.put(topicGroup, channel, msg);
//向通道发送消息的方法
stringRedisTemplate.convertAndSend(topicGroup + "-" + channel, msg);
return true;
}
/*
* 订阅回调
*
* @param msg
* @param redisSubscribeCallback
*/
public void subscribeConfig(String msg, RedisSubscribeCallback redisSubscribeCallback) {
redisSubscribeCallback.callback(msg);
}
/*
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time) {
return redisTemplate.execute(new RedisCallback() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
long rawTimeout = TimeoutUtils.toMillis(time, TimeUnit.SECONDS);
try {
return connection.pExpire(key.getBytes(), rawTimeout);
} catch (Exception e) {
// Driver may not support pExpire or we may be running on
// Redis 2.4
return connection.expire(key.getBytes(), TimeoutUtils.toSeconds(rawTimeout, TimeUnit.SECONDS));
}
}
});
}
/*
* 根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.execute(new RedisCallback() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
try {
return connection.pTtl(key.getBytes(), TimeUnit.SECONDS);
} catch (Exception e) {
// Driver may not support pTtl or we may be running on Redis
// 2.4
return connection.ttl(key.getBytes(), TimeUnit.SECONDS);
}
}
});
}
/*
* 判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
return redisTemplate.execute((RedisCallback) connection -> connection.exists(key.getBytes()));
}
// ============================Object=============================
/*
* 普通缓存获取
*
* @param key 键
* @return 值
*/
public Object get(String key) {
Object value = redisTemplate.execute(new RedisCallback() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
// redis info
byte[] temp = null;
temp = connection.get(key.getBytes());
connection.close();
return redisObjectSerializer.deserialize(temp);
}
});
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/*
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.execute((RedisCallback) connection -> {
// redis info
byte[] values = redisObjectSerializer.serialize(value);
connection.set(key.getBytes(), values);
connection.close();
return 1L;
});
return true;
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("set-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return false;
}
}
/*
* 普通缓存放入并设置时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.execute((RedisCallback) connection -> {
// redis info
byte[] values = redisObjectSerializer.serialize(value);
connection.set(key.getBytes(), values);
connection.expire(key.getBytes(), 60 * time);
connection.close();
return 1L;
});
} else {
set(key, value);
}
return true;
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("set-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return false;
}
}
/*
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.execute((RedisCallback) connection -> {
return connection.incrBy(key.getBytes(), delta);
});
}
/*
* 递减
*
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.execute((RedisCallback) connection -> {
return connection.incrBy(key.getBytes(), -delta);
});
}
/*
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
List keyList = new ArrayList<>(key.length);
Collections.addAll(keyList,key);
redisTemplate.delete(keyList);
}
}
}
/*
* 写入缓存
*
* @param key
* @param offset 位 8Bit=1Byte
* @return
*/
public boolean setBit(String key, long offset, boolean isShow) {
boolean result = false;
try {
ValueOperations operations = redisTemplate.opsForValue();
operations.setBit(key, offset, isShow);
result = true;
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("setBit-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return false;
}
return result;
}
/*
* 写入缓存
*
* @param key
* @param offset
* @return
*/
public boolean getBit(String key, long offset) {
boolean result = false;
try {
ValueOperations operations = redisTemplate.opsForValue();
result = operations.getBit(key, offset);
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("getBit-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return false;
}
return result;
}
//===============================list=================================
/*
* 获取list缓存的内容
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lGet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return null;
}
}
/*
* 获取list缓存的长度
*
* @param key 键
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lGetListSize-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return 0;
}
}
/*
* 通过索引 获取list中的值
*
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lGetIndex-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return null;
}
}
public Object lLeftPop(String key) {
try {
return redisTemplate.opsForList().leftPop(key);
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lLeftPop-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return null;
}
}
/*
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return false;
}
}
/*
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) expire(key, time);
return true;
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return false;
}
}
/*
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return false;
}
}
/*
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) expire(key, time);
return true;
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lSet-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return false;
}
}
/*
* 根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lUpdateIndex-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return false;
}
}
/*
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("lRemove-" + stackTraceElement.getMethodName() + "--" + stackTraceElement.getLineNumber());
return 0;
}
}
// ================================Map=================================
/*
* 哈希 添加
*
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}
/*
* 哈希获取数据
*
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey) {
HashOperations hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
public Long hmDel(String key, Object... hashKey) {
HashOperations hash = redisTemplate.opsForHash();
if (hashKey != null && hashKey.length > 0) {
if (hashKey.length == 1) {
return hash.delete(key, hashKey);
} else {
return hash.delete(key, CollectionUtils.arrayToList(key));
}
}
return 0L;
}
// ================================set=================================
/*
* 集合添加
*
* @param key
* @param value
*/
public void add(String key, Object value) {
SetOperations set = redisTemplate.opsForSet();
set.add(key, value);
}
/*
* 集合获取
*
* @param key
* @return
*/
public Set setMembers(String key) {
SetOperations set = redisTemplate.opsForSet();
return set.members(key);
}
/*
* 有序集合添加
*
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key, Object value, double scoure) {
ZSetOperations zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/*
* 有序集合按分数获取
*
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations zset = redisTemplate.opsForZSet();
redisTemplate.opsForValue();
return zset.rangeByScore(key, scoure, scoure1);
}
/*
* 有序集合获取
*
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set zRange(String key, long scoure, long scoure1) {
ZSetOperations zset = redisTemplate.opsForZSet();
redisTemplate.opsForValue();
return zset.range(key, scoure, scoure1);
}
/*
* 有序集合按分数删除
*
* @param key
* @param value
* @param scoure
*/
public Long zRemoveRangeByScore(String key, double scoure, double scoure1) {
ZSetOperations zset = redisTemplate.opsForZSet();
return zset.removeRangeByScore(key, scoure, scoure);
}
/*
* 有序集合删除
*
* @param key
* @param value
* @param scoure
*/
public Long zRemove(String key, Object... object) {
ZSetOperations zset = redisTemplate.opsForZSet();
return zset.remove(key, object);
}
/*
* 有序集合获取排名
*
* @param key 集合名称
* @param value 值
*/
public Long zRank(String key, Object value) {
ZSetOperations zset = redisTemplate.opsForZSet();
return zset.rank(key, value);
}
/*
* 有序集合获取排名
*
* @param key
*/
public Set> zRankWithScore(String key, long start, long end) {
ZSetOperations zset = redisTemplate.opsForZSet();
Set> ret = zset.rangeWithScores(key, start, end);
return ret;
}
/*
* 有序集合获取
*
* @param key
* @param value
*/
public Double zGetScore(String key, Object value) {
ZSetOperations zset = redisTemplate.opsForZSet();
return zset.score(key, value);
}
/*
* 有序集合添加分数
*
* @param key
* @param value
* @param scoure
*/
public Double incrementScore(String key, Object value, double scoure) {
ZSetOperations zset = redisTemplate.opsForZSet();
return zset.incrementScore(key, value, scoure);
}
/*
* 有序集合获取排名
*
* @param key
*/
public Set> reverseZRankWithScore(String key, long start, long end) {
ZSetOperations zset = redisTemplate.opsForZSet();
Set> ret = zset.reverseRangeByScoreWithScores(key, start, end);
return ret;
}
/*
* 有序集合获取排名
*
* @param key
*/
public Set> reverseZRankWithRank(String key, long start, long end) {
ZSetOperations zset = redisTemplate.opsForZSet();
Set> ret = zset.reverseRangeWithScores(key, start, end);
return ret;
}
/*
* 添加经纬度信息
* map.put("北京" ,new Point(116.405285 ,39.904989)) //redis 命令:geoadd cityGeo 116.405285 39.904989 "北京"
*/
public Long addGeoPoint(String key , Map map) {
return redisTemplate.opsForGeo().add(key, map);
}
/*
* 查找指定key的经纬度信息
* redis命令:geopos cityGeo 北京
* @param key
* @param member
* @return
*/
public Point geoGetPoint(String key , String member) {
List lists = redisTemplate.opsForGeo().position(key, member) ;
return lists.get(0);
}
/*
* 返回两个地方的距离,可以指定单位
* redis命令:geodist cityGeo 北京 上海
* @param key
* @param srcMember
* @param targetMember
* @return
*/
public Distance geoDistance(String key, String srcMember , String targetMember ) {
Distance distance = redisTemplate.opsForGeo().distance(key, srcMember, targetMember ,Metrics.KILOMETERS);
return distance;
}
/*
* 根据指定的地点查询半径在指定范围内的位置
* redis命令:georadiusbymember cityGeo 北京 100 km WITHDIST WITHCOORD ASC COUNT 5
* @param key
* @param member
* @param distance
* @return
*/
public GeoResults geoRadiusByMember(String key, String member , double distance ) {
return redisTemplate.opsForGeo().radius(key, member, new Distance(distance,Metrics.KILOMETERS )) ;
}
/*
* 根据给定的经纬度,返回半径不超过指定距离的元素
* redis命令:georadius cityGeo 116.405285 39.904989 100 km WITHDIST WITHCOORD ASC COUNT 5
* @param key
* @param circle
* @param distance
* @return
*/
public GeoResults geoRadiusByCircle(String key, Circle circle , double distance ) {
return redisTemplate.opsForGeo().radius(key, circle, new Distance(distance,Metrics.KILOMETERS )) ;
}
/**
* 根据前缀模糊查询
*
* @param prex
* @return
*/
public Set getKeys(String prex) {
return redisTemplate.keys(prex);
}
public Long getDBSize() {
return (Long) redisTemplate.execute((RedisCallback)
RedisServerCommands::dbSize);
}
public String flushDB() {
return (String) redisTemplate.execute(new RedisCallback() {
@Override
public String doInRedis(RedisConnection connection) throws DataAccessException {
connection.flushDb();
return "ok";
}
});
}
private static long lockTimeout = 5*1000L; //锁定时间5s
/**
* 加锁
*
* @param key
* @return
*/
public boolean lock(String key) {
long currvalue = System.currentTimeMillis();
String value = currvalue+lockTimeout+"";
//未加锁,则加锁
if (redisTemplate.opsForValue().setIfAbsent(key, value)) {
return true;
}
do {
//获取锁解锁时间
String currentValue = (String)redisTemplate.opsForValue().get(key);
//如果锁过期
if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) {
//获得上一个锁的时间
String olcValue = (String)redisTemplate.opsForValue().getAndSet(key, value);
if (!StringUtils.isEmpty(olcValue) && olcValue.equals(currentValue)) {
return true;
}
}
try {
// log.info("等待500 ms key:{},value:{},cur:{}, 剩余:{}",key,value, System.currentTimeMillis(), Long.parseLong(value)-System.currentTimeMillis());
Thread.sleep(500);
} catch (InterruptedException e) {
}
}while(Long.parseLong(value) > System.currentTimeMillis());
return false;
}
/**
* 解锁
*
* @param key
*/
public void unlock(String key) {
long currvalue = System.currentTimeMillis();
try {
String value = currvalue+lockTimeout+"";
String currentVlue = (String)redisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(currentVlue) && currentVlue.equals(value)) {
redisTemplate.opsForValue().getOperations().delete(key);
}
} catch (Exception e) {
log.error("【redis分布式锁】 解锁异常" + e.getMessage(), e);
}
}
}