|
@@ -0,0 +1,693 @@
|
|
|
+package com.mooctest.crowd.site.util;
|
|
|
+
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.domain.Sort;
|
|
|
+import org.springframework.data.geo.Circle;
|
|
|
+import org.springframework.data.geo.Distance;
|
|
|
+import org.springframework.data.geo.GeoResults;
|
|
|
+import org.springframework.data.geo.Point;
|
|
|
+import org.springframework.data.redis.connection.RedisGeoCommands;
|
|
|
+import org.springframework.data.redis.connection.RedisStringCommands;
|
|
|
+import org.springframework.data.redis.connection.ReturnType;
|
|
|
+import org.springframework.data.redis.core.GeoOperations;
|
|
|
+import org.springframework.data.redis.core.RedisCallback;
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
+import org.springframework.data.redis.core.ZSetOperations;
|
|
|
+import org.springframework.data.redis.core.types.Expiration;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+@Component
|
|
|
+public class RedisHelper {
|
|
|
+ public static final String UNLOCK_LUA;
|
|
|
+
|
|
|
+ static {
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ sb.append("if redis.call(\"get\",KEYS[1]) == ARGV[1] ");
|
|
|
+ sb.append("then ");
|
|
|
+ sb.append(" return redis.call(\"del\",KEYS[1]) ");
|
|
|
+ sb.append("else ");
|
|
|
+ sb.append(" return 0 ");
|
|
|
+ sb.append("end ");
|
|
|
+ UNLOCK_LUA = sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisTemplate<String, Object> redisTemplate;
|
|
|
+ // =============================common============================
|
|
|
+ /**
|
|
|
+ * 指定缓存失效时间
|
|
|
+ * @param key 键
|
|
|
+ * @param time 时间(秒)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean expire(String key, long time) {
|
|
|
+ try {
|
|
|
+ if (time > 0) {
|
|
|
+ redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 根据key 获取过期时间
|
|
|
+ * @param key 键 不能为null
|
|
|
+ * @return 时间(秒) 返回0代表为永久有效
|
|
|
+ */
|
|
|
+ public long getExpire(String key) {
|
|
|
+ return redisTemplate.getExpire(key, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 判断key是否存在
|
|
|
+ * @param key 键
|
|
|
+ * @return true 存在 false不存在
|
|
|
+ */
|
|
|
+ public boolean hasKey(String key) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.hasKey(key);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 删除缓存
|
|
|
+ * @param key 可以传一个值 或多个
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public void del(String... key) {
|
|
|
+ if (key != null && key.length > 0) {
|
|
|
+ if (key.length == 1) {
|
|
|
+ redisTemplate.delete(key[0]);
|
|
|
+ } else {
|
|
|
+ redisTemplate.delete((List)CollectionUtils.arrayToList(key));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // ============================String=============================
|
|
|
+ /**
|
|
|
+ * 普通缓存获取
|
|
|
+ * @param key 键
|
|
|
+ * @return 值
|
|
|
+ */
|
|
|
+ public Object get(String key) {
|
|
|
+ return key == null ? null : redisTemplate.opsForValue().get(key);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 普通缓存放入
|
|
|
+ * @param key 键
|
|
|
+ * @param value 值
|
|
|
+ * @return true成功 false失败
|
|
|
+ */
|
|
|
+ public boolean set(String key, Object value) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForValue().set(key, value);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ 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.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
|
|
+ } else {
|
|
|
+ set(key, value);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 递增
|
|
|
+ * @param key 键
|
|
|
+ * @param delta 要增加几(大于0)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public long incr(String key, long delta) {
|
|
|
+ if (delta < 0) {
|
|
|
+ throw new RuntimeException("递增因子必须大于0");
|
|
|
+ }
|
|
|
+ return redisTemplate.opsForValue().increment(key, delta);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 递减
|
|
|
+ * @param key 键
|
|
|
+ * @param delta 要减少几(小于0)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public long decr(String key, long delta) {
|
|
|
+ if (delta < 0) {
|
|
|
+ throw new RuntimeException("递减因子必须大于0");
|
|
|
+ }
|
|
|
+ return redisTemplate.opsForValue().increment(key, -delta);
|
|
|
+ }
|
|
|
+ // ================================Map=================================
|
|
|
+ /**
|
|
|
+ * HashGet
|
|
|
+ * @param key 键 不能为null
|
|
|
+ * @param item 项 不能为null
|
|
|
+ * @return 值
|
|
|
+ */
|
|
|
+ public Object hget(String key, String item) {
|
|
|
+ return redisTemplate.opsForHash().get(key, item);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 获取hashKey对应的所有键值
|
|
|
+ * @param key 键
|
|
|
+ * @return 对应的多个键值
|
|
|
+ */
|
|
|
+ public Map<Object, Object> hmget(String key) {
|
|
|
+ return redisTemplate.opsForHash().entries(key);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * HashSet
|
|
|
+ * @param key 键
|
|
|
+ * @param map 对应多个键值
|
|
|
+ * @return true 成功 false 失败
|
|
|
+ */
|
|
|
+ public boolean hmset(String key, Map<String, Object> map) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForHash().putAll(key, map);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * HashSet 并设置时间
|
|
|
+ * @param key 键
|
|
|
+ * @param map 对应多个键值
|
|
|
+ * @param time 时间(秒)
|
|
|
+ * @return true成功 false失败
|
|
|
+ */
|
|
|
+ public boolean hmset(String key, Map<String, Object> map, long time) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForHash().putAll(key, map);
|
|
|
+ if (time > 0) {
|
|
|
+ expire(key, time);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 向一张hash表中放入数据,如果不存在将创建
|
|
|
+ * @param key 键
|
|
|
+ * @param item 项
|
|
|
+ * @param value 值
|
|
|
+ * @return true 成功 false失败
|
|
|
+ */
|
|
|
+ public boolean hset(String key, String item, Object value) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForHash().put(key, item, value);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public long hSize(String key) {
|
|
|
+ return redisTemplate.opsForHash().size(key);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 向一张hash表中放入数据,如果不存在将创建
|
|
|
+ * @param key 键
|
|
|
+ * @param item 项
|
|
|
+ * @param value 值
|
|
|
+ * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
|
|
|
+ * @return true 成功 false失败
|
|
|
+ */
|
|
|
+ public boolean hset(String key, String item, Object value, long time) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForHash().put(key, item, value);
|
|
|
+ if (time > 0) {
|
|
|
+ expire(key, time);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 删除hash表中的值
|
|
|
+ * @param key 键 不能为null
|
|
|
+ * @param item 项 可以使多个 不能为null
|
|
|
+ */
|
|
|
+ public void hdel(String key, Object... item) {
|
|
|
+ redisTemplate.opsForHash().delete(key, item);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 判断hash表中是否有该项的值
|
|
|
+ * @param key 键 不能为null
|
|
|
+ * @param item 项 不能为null
|
|
|
+ * @return true 存在 false不存在
|
|
|
+ */
|
|
|
+ public boolean hHasKey(String key, String item) {
|
|
|
+ return redisTemplate.opsForHash().hasKey(key, item);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * hash递增 如果不存在,就会创建一个 并把新增后的值返回
|
|
|
+ * @param key 键
|
|
|
+ * @param item 项
|
|
|
+ * @param by 要增加几(大于0)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public double hincr(String key, String item, double by) {
|
|
|
+ return redisTemplate.opsForHash().increment(key, item, by);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * hash递减
|
|
|
+ * @param key 键
|
|
|
+ * @param item 项
|
|
|
+ * @param by 要减少记(小于0)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public double hdecr(String key, String item, double by) {
|
|
|
+ return redisTemplate.opsForHash().increment(key, item, -by);
|
|
|
+ }
|
|
|
+ // ============================set=============================
|
|
|
+ /**
|
|
|
+ * 根据key获取Set中的所有值
|
|
|
+ * @param key 键
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Set<Object> sGet(String key) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForSet().members(key);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据value从一个set中查询,是否存在
|
|
|
+ * @param key 键
|
|
|
+ * @param value 值
|
|
|
+ * @return true 存在 false不存在
|
|
|
+ */
|
|
|
+ public boolean sHasKey(String key, Object value) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForSet().isMember(key, value);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 将数据放入set缓存
|
|
|
+ * @param key 键
|
|
|
+ * @param values 值 可以是多个
|
|
|
+ * @return 成功个数
|
|
|
+ */
|
|
|
+ public long sSet(String key, Object... values) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForSet().add(key, values);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 将set数据放入缓存
|
|
|
+ * @param key 键
|
|
|
+ * @param time 时间(秒)
|
|
|
+ * @param values 值 可以是多个
|
|
|
+ * @return 成功个数
|
|
|
+ */
|
|
|
+ public long sSetAndTime(String key, long time, Object... values) {
|
|
|
+ try {
|
|
|
+ Long count = redisTemplate.opsForSet().add(key, values);
|
|
|
+ if (time > 0)
|
|
|
+ expire(key, time);
|
|
|
+ return count;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 获取set缓存的长度
|
|
|
+ * @param key 键
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public long sGetSetSize(String key) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForSet().size(key);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Set<Object> sDiff(String key1, String key2) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForSet().difference(key1, key2);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Set<Object> sDiff(String key1, Collection c) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForSet().difference(key1, c);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public long sIntersectAndStore(String key1, String key2, String key) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForSet().intersectAndStore(key1, key2, key);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return 0L;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 移除值为value的
|
|
|
+ * @param key 键
|
|
|
+ * @param values 值 可以是多个
|
|
|
+ * @return 移除的个数
|
|
|
+ */
|
|
|
+ public long setRemove(String key, Object... values) {
|
|
|
+ try {
|
|
|
+ Long count = redisTemplate.opsForSet().remove(key, values);
|
|
|
+ return count;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // ===============================list=================================
|
|
|
+ /**
|
|
|
+ * 获取list缓存的内容
|
|
|
+ * @param key 键
|
|
|
+ * @param start 开始
|
|
|
+ * @param end 结束 0 到 -1代表所有值
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<Object> lGet(String key, long start, long end) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForList().range(key, start, end);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 获取list缓存的长度
|
|
|
+ * @param key 键
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public long lGetListSize(String key) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForList().size(key);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ 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) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 将list放入缓存
|
|
|
+ * @param key 键
|
|
|
+ * @param value 值
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean lSet(String key, Object value) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForList().rightPush(key, value);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ 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) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 将list放入缓存
|
|
|
+ * @param key 键
|
|
|
+ * @param value 值
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean lSet(String key, List<Object> value) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForList().rightPushAll(key, value);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 将list放入缓存
|
|
|
+ *
|
|
|
+ * @param key 键
|
|
|
+ * @param value 值
|
|
|
+ * @param time 时间(秒)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean lSet(String key, List<Object> value, long time) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForList().rightPushAll(key, value);
|
|
|
+ if (time > 0)
|
|
|
+ expire(key, time);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ 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) {
|
|
|
+ e.printStackTrace();
|
|
|
+ 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) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean geoSet(String key, double latitude, double longitude, Object value) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForGeo().add(key, new Point(longitude, latitude), value);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean removeGeo(String key, Object...values) {
|
|
|
+ try {
|
|
|
+ GeoOperations geoOps = redisTemplate.opsForGeo();
|
|
|
+ geoOps.remove(key, values);
|
|
|
+ } catch (Throwable t) {
|
|
|
+ throw new RuntimeException(t);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Distance distanceGeo(String key, Object member1, String member2) {
|
|
|
+ try {
|
|
|
+ GeoOperations geoOps = redisTemplate.opsForGeo();
|
|
|
+ return geoOps.distance(key, member1, member2);
|
|
|
+ } catch (Throwable t) {
|
|
|
+ throw new RuntimeException(t);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public GeoResults<RedisGeoCommands.GeoLocation> radiusGeo(String key, double latitude, double longitude, double distance, Sort.Direction direction, long limit) {
|
|
|
+ try {
|
|
|
+ GeoOperations geoOps = redisTemplate.opsForGeo();
|
|
|
+ //设置geo查询参数
|
|
|
+ RedisGeoCommands.GeoRadiusCommandArgs geoRadiusArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
|
|
|
+ geoRadiusArgs = geoRadiusArgs.includeCoordinates().includeDistance();//查询返回结果包括距离和坐标
|
|
|
+ if (Sort.Direction.ASC.equals(direction)) {//按查询出的坐标距离中心坐标的距离进行排序
|
|
|
+ geoRadiusArgs.sortAscending();
|
|
|
+ } else if (Sort.Direction.DESC.equals(direction)) {
|
|
|
+ geoRadiusArgs.sortDescending();
|
|
|
+ }
|
|
|
+ geoRadiusArgs.limit(limit);//限制查询数量
|
|
|
+ GeoResults<RedisGeoCommands.GeoLocation> radiusGeo = geoOps.radius(key, new Circle(new Point(longitude, latitude), new Distance(distance, RedisGeoCommands.DistanceUnit.METERS)), geoRadiusArgs);
|
|
|
+ return radiusGeo;
|
|
|
+ } catch (Throwable t) {
|
|
|
+ throw new RuntimeException(t);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<Point> geoPosition(String key, Object...vals) {
|
|
|
+ GeoOperations geoOps = redisTemplate.opsForGeo();
|
|
|
+ return geoOps.position(key, vals);
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean zSet(String key, Object val, double score) {
|
|
|
+ redisTemplate.opsForZSet().add(key, val, score);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean zSet(String key, Set<ZSetOperations.TypedTuple<Object>> typedTuples) {
|
|
|
+ redisTemplate.opsForZSet().add(key, typedTuples);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public long zCard(String key) {
|
|
|
+ return redisTemplate.opsForZSet().zCard(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 升序指定起始和结束位置删除
|
|
|
+ public boolean zRemoveRange(String key, long index1, long index2) {
|
|
|
+ redisTemplate.opsForZSet().removeRange(key, index1, index2);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ //正序
|
|
|
+ public Set zRange(String key, long index1, long index2) {
|
|
|
+ return redisTemplate.opsForZSet().range(key, index1, index2);
|
|
|
+ }
|
|
|
+
|
|
|
+ //倒序
|
|
|
+ public Set zReverseRange(String key, long index1, long index2) {
|
|
|
+ return redisTemplate.opsForZSet().reverseRange(key, index1, index2);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Set zRangeByScore(String key, double score1, double score2) {
|
|
|
+ return redisTemplate.opsForZSet().rangeByScore(key, score1, score2);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Set zReverseRangeByScore(String key, double score1, double score2) {
|
|
|
+ return redisTemplate.opsForZSet().reverseRangeByScore(key, score1, score2);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Set<ZSetOperations.TypedTuple<Object>> zRangeByScoreWithScores(String key, double score1, double score2) {
|
|
|
+ Set<ZSetOperations.TypedTuple<Object>> set = redisTemplate.opsForZSet().rangeByScoreWithScores(key, score1, score2);
|
|
|
+ return set;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean zRemove(String key, Object... objs) {
|
|
|
+ redisTemplate.opsForZSet().remove(key, objs);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Set<String> keys(String pattern) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.keys(pattern);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean lock(String key, String requestId, int expireSecond) {
|
|
|
+ try {
|
|
|
+ RedisCallback<Boolean> callback = (connection) -> {
|
|
|
+// RedisAsyncCommandsImpl commands = (RedisAsyncCommandsImpl) connection.getNativeConnection();
|
|
|
+ return connection.set(key.getBytes(), requestId.getBytes(), Expiration.seconds(expireSecond), RedisStringCommands.SetOption.SET_IF_ABSENT);
|
|
|
+ };
|
|
|
+ return redisTemplate.execute(callback);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean releaseLock(String key, String requestId) {
|
|
|
+ // 释放锁的时候,有可能因为持锁之后方法执行时间大于锁的有效期,此时有可能已经被另外一个线程持有锁,所以不能直接删除
|
|
|
+ try {
|
|
|
+ List<String> keys = new ArrayList<>();
|
|
|
+ keys.add(key);
|
|
|
+ List<String> args = new ArrayList<>();
|
|
|
+ args.add(requestId);
|
|
|
+ // 使用lua脚本删除redis中匹配value的key,可以避免由于方法执行时间过长而redis锁自动过期失效的时候误删其他线程的锁
|
|
|
+ RedisCallback<Boolean> callback = (connection) -> {
|
|
|
+ Boolean result = connection.eval(UNLOCK_LUA.getBytes(), ReturnType.BOOLEAN, 1, key.getBytes(), requestId.getBytes());
|
|
|
+ return result;
|
|
|
+ };
|
|
|
+ return redisTemplate.execute(callback);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void convertAndSend(String channel, Object message) {
|
|
|
+ redisTemplate.convertAndSend(channel, message);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|