|
@@ -0,0 +1,1075 @@
|
|
|
+package com.zhentao.utils;
|
|
|
+
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.dao.DataAccessException;
|
|
|
+import org.springframework.data.redis.connection.RedisConnection;
|
|
|
+import org.springframework.data.redis.core.BoundListOperations;
|
|
|
+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.support.atomic.RedisAtomicInteger;
|
|
|
+import org.springframework.data.redis.support.atomic.RedisAtomicLong;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+/**
|
|
|
+ * redisTemplate封装
|
|
|
+ */
|
|
|
+@Component
|
|
|
+public class RedisUtil {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private final RedisTemplate redisTemplate;
|
|
|
+
|
|
|
+ //锁名称前缀
|
|
|
+ public static final String LOCK_PREFIX = "redis_lock";
|
|
|
+ //加锁失效时间,毫秒
|
|
|
+ public static final int LOCK_EXPIRE = 10; // ms
|
|
|
+
|
|
|
+ public static Integer workId=0;
|
|
|
+ public static Integer dataId=0;
|
|
|
+
|
|
|
+
|
|
|
+ public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
|
|
|
+ this.redisTemplate = redisTemplate;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * redis发布消息
|
|
|
+ *
|
|
|
+ * @param channel
|
|
|
+ * @param message
|
|
|
+ */
|
|
|
+ public void sendMessage(String channel, String message) {
|
|
|
+ redisTemplate.convertAndSend(channel, message);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 指定缓存失效时间
|
|
|
+ *
|
|
|
+ * @param key 键
|
|
|
+ * @param time 时间(秒)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean expire(String key, long time, TimeUnit timeUnit) {
|
|
|
+ try {
|
|
|
+ if (time > 0) {
|
|
|
+ redisTemplate.expire(key, time, timeUnit);
|
|
|
+ }
|
|
|
+ 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(CollectionUtils.arrayToList(key));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除缓存
|
|
|
+ *
|
|
|
+ * @param keys 集合
|
|
|
+ */
|
|
|
+ public void del(Collection<String> keys) {
|
|
|
+ redisTemplate.delete(keys);
|
|
|
+ }
|
|
|
+
|
|
|
+ //============================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, TimeUnit timeUnit) {
|
|
|
+ try {
|
|
|
+ if (time > 0) {
|
|
|
+ redisTemplate.opsForValue().set(key, value, time, timeUnit);
|
|
|
+ } 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().decrement(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, TimeUnit timeUnit) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForHash().putAll(key, map);
|
|
|
+ if (time > 0) {
|
|
|
+ expire(key, time, timeUnit);
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 向一张hash表中放入数据,如果不存在将创建
|
|
|
+ *
|
|
|
+ * @param key 键
|
|
|
+ * @param item 项
|
|
|
+ * @param value 值
|
|
|
+ * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
|
|
|
+ * @return true 成功 false失败
|
|
|
+ */
|
|
|
+ public boolean hset(String key, String item, Object value, long time, TimeUnit timeUnit) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForHash().put(key, item, value);
|
|
|
+ if (time > 0) {
|
|
|
+ expire(key, time, timeUnit);
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获得锁
|
|
|
+ *
|
|
|
+ * @param lock
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean lock(String lock) {
|
|
|
+ return (boolean) redisTemplate.execute((RedisCallback) connection -> {
|
|
|
+ //获取时间毫秒值
|
|
|
+ long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1;
|
|
|
+ //获取锁
|
|
|
+ Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());
|
|
|
+ if (acquire) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ byte[] bytes = connection.get(lock.getBytes());
|
|
|
+ //非空判断
|
|
|
+ if (Objects.nonNull(bytes) && bytes.length > 0) {
|
|
|
+ long expireTime = Long.parseLong(new String(bytes));
|
|
|
+ // 如果锁已经过期
|
|
|
+ if (expireTime < System.currentTimeMillis()) {
|
|
|
+ // 重新加锁,防止死锁
|
|
|
+ byte[] set = connection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes());
|
|
|
+ return Long.parseLong(new String(set)) < System.currentTimeMillis();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获得锁
|
|
|
+ *
|
|
|
+ * @param lock
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean lock(String lock,Long timeOut) {
|
|
|
+ return (boolean) redisTemplate.execute((RedisCallback) connection -> {
|
|
|
+ //获取时间毫秒值
|
|
|
+ long expireAt = System.currentTimeMillis() + timeOut + 1;
|
|
|
+ //获取锁
|
|
|
+ Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());
|
|
|
+ if (acquire) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ byte[] bytes = connection.get(lock.getBytes());
|
|
|
+ //非空判断
|
|
|
+ if (Objects.nonNull(bytes) && bytes.length > 0) {
|
|
|
+ long expireTime = Long.parseLong(new String(bytes));
|
|
|
+ // 如果锁已经过期
|
|
|
+ if (expireTime < System.currentTimeMillis()) {
|
|
|
+ // 重新加锁,防止死锁
|
|
|
+ byte[] set = connection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes());
|
|
|
+ return Long.parseLong(new String(set)) < System.currentTimeMillis();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除锁
|
|
|
+ *
|
|
|
+ * @param key
|
|
|
+ */
|
|
|
+ public void deleteLock(String key) {
|
|
|
+
|
|
|
+ redisTemplate.delete(key);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 加锁,⽆阻塞
|
|
|
+ * <p>
|
|
|
+ * 锁
|
|
|
+ *
|
|
|
+ * @param key 请求标识
|
|
|
+ * @param userId 超期时间
|
|
|
+ * @param expireTime 上锁时间,单位TimeUnit.SECONDS
|
|
|
+ * @param timeout 等待时间,单位TimeUnit.SECONDS
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Boolean lock(String key, long expireTime, Long userId, long timeout) {
|
|
|
+ Long start = System.currentTimeMillis();
|
|
|
+ //在⼀定时间内获取锁,超时则返回错误
|
|
|
+//
|
|
|
+ for (; ; ) {
|
|
|
+//,则证明获取锁成功
|
|
|
+//Set
|
|
|
+ // OK
|
|
|
+ Boolean ret = redisTemplate.opsForValue().setIfAbsent(key, userId, expireTime, TimeUnit.SECONDS);
|
|
|
+ if (ret != null && ret) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ // 否则循环等待,在
|
|
|
+ // 时间内仍未获取到锁,则获取失败
|
|
|
+ long end = System.currentTimeMillis() - start;
|
|
|
+ if (end >= timeout * 1000) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public Boolean lock(String key, long expireTime, Long userId) {
|
|
|
+ Boolean ret = redisTemplate.opsForValue().setIfAbsent(key, userId, expireTime, TimeUnit.SECONDS);
|
|
|
+ return ret != null && ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Boolean unlock(String key, Long userId) {
|
|
|
+ Object o = redisTemplate.opsForValue().get(key);
|
|
|
+ if(userId.equals(o)){
|
|
|
+ return redisTemplate.delete(key);
|
|
|
+ }else{
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 将set数据放入缓存
|
|
|
+ *
|
|
|
+ * @param key 键
|
|
|
+ * @param time 时间(秒)
|
|
|
+ * @param values 值 可以是多个
|
|
|
+ * @return 成功个数
|
|
|
+ */
|
|
|
+ public long sSetAndTime(String key, long time, TimeUnit timeUnit, Object... values) {
|
|
|
+ try {
|
|
|
+ Long count = redisTemplate.opsForSet().add(key, values);
|
|
|
+ if (time > 0) {
|
|
|
+ expire(key, time, timeUnit);
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 移除值为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> listGet(String key, long start, long end) {
|
|
|
+ try {
|
|
|
+ return redisTemplate.opsForList().range(key, start, end);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 弹出对象
|
|
|
+ * @param key
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Object popLeftList(String key){
|
|
|
+ return redisTemplate.opsForList().leftPop(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取list缓存的长度
|
|
|
+ *
|
|
|
+ * @param key 键
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public long listSize(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 listGetIndex(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 listSet(String key, Object value) {
|
|
|
+ try {
|
|
|
+
|
|
|
+ redisTemplate.opsForList().rightPush(key, value);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void listTrim(String key, long start,long end) {
|
|
|
+ try {
|
|
|
+
|
|
|
+ redisTemplate.opsForList().trim(key,start,end);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将list放入缓存
|
|
|
+ *
|
|
|
+ * @param key 键
|
|
|
+ * @param value 值
|
|
|
+ * @param time 时间(秒)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean listSet(String key, Object value, long time, TimeUnit timeUnit) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForList().rightPush(key, value);
|
|
|
+ if (time > 0) {
|
|
|
+ expire(key, time, timeUnit);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将list放入缓存
|
|
|
+ *
|
|
|
+ * @param key 键
|
|
|
+ * @param value 值
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean listSet(String key, List<Object> value) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForList().rightPushAll(key, value);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * list大小
|
|
|
+ * @param key
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Long getListSize(String key){
|
|
|
+ return redisTemplate.opsForList().size(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将list放入缓存
|
|
|
+ *
|
|
|
+ * @param key 键
|
|
|
+ * @param value 值
|
|
|
+ * @param time 时间(秒)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean listSet(String key, List<Object> value, long time, TimeUnit timeUnit) {
|
|
|
+ try {
|
|
|
+ redisTemplate.opsForList().rightPushAll(key, value);
|
|
|
+ if (time > 0) {
|
|
|
+ expire(key, time, timeUnit);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据索引修改list中的某条数据
|
|
|
+ *
|
|
|
+ * @param key 键
|
|
|
+ * @param index 索引
|
|
|
+ * @param value 值
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean listUpdateIndex(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 listRemove(String key, long count, Object value) {
|
|
|
+ try {
|
|
|
+ Long remove = redisTemplate.opsForList().remove(key, count, value);
|
|
|
+ return remove;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 模糊查询获取key值
|
|
|
+ *
|
|
|
+ * @param pattern
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Set keys(String pattern) {
|
|
|
+ return redisTemplate.keys(pattern);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用Redis的消息队列
|
|
|
+ *
|
|
|
+ * @param channel
|
|
|
+ * @param message 消息内容
|
|
|
+ */
|
|
|
+ public void convertAndSend(String channel, Object message) {
|
|
|
+ redisTemplate.convertAndSend(channel, message);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //=========BoundListOperations 用法 start============
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将数据添加到Redis的list中(从右边添加)
|
|
|
+ *
|
|
|
+ * @param listKey
|
|
|
+ * @param time 过期时间
|
|
|
+ * @param values 待添加的数据
|
|
|
+ */
|
|
|
+ public void addToListRight(String listKey, long time, Object... values) {
|
|
|
+ //绑定操作
|
|
|
+ BoundListOperations<String, Object> boundValueOperations = redisTemplate.boundListOps(listKey);
|
|
|
+ //插入数据
|
|
|
+ boundValueOperations.rightPushAll(values);
|
|
|
+ //设置过期时间
|
|
|
+ boundValueOperations.expire(time, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据起始结束序号遍历Redis中的list
|
|
|
+ *
|
|
|
+ * @param listKey
|
|
|
+ * @param start 起始序号
|
|
|
+ * @param end 结束序号
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<Object> rangeList(String listKey, long start, long end) {
|
|
|
+ //绑定操作
|
|
|
+ BoundListOperations<String, Object> boundValueOperations = redisTemplate.boundListOps(listKey);
|
|
|
+ //查询数据
|
|
|
+ return boundValueOperations.range(start, end);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 弹出右边的值 --- 并且移除这个值
|
|
|
+ *
|
|
|
+ * @param listKey
|
|
|
+ */
|
|
|
+ public Object rifhtPop(String listKey) {
|
|
|
+ //绑定操作
|
|
|
+ BoundListOperations<String, Object> boundValueOperations = redisTemplate.boundListOps(listKey);
|
|
|
+ return boundValueOperations.rightPop();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param key
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Long getIncr(String key) {
|
|
|
+ RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
|
|
|
+ Long increment = entityIdCounter.getAndIncrement();
|
|
|
+ return increment;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public synchronized Integer getSequenceId() {
|
|
|
+ String key = "sms_sequence_id";
|
|
|
+ RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
|
|
|
+ int sequenceId = idCount.getAndIncrement();
|
|
|
+ if (sequenceId <= 1000 || sequenceId >= 1000000000) {
|
|
|
+ idCount.set(1000);
|
|
|
+ sequenceId = idCount.getAndIncrement();
|
|
|
+ return sequenceId;
|
|
|
+ }
|
|
|
+ return sequenceId;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setCount(String key ,int initValue){
|
|
|
+ RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
|
|
|
+ idCount.set(initValue);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Integer getCount(String key) {
|
|
|
+ RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
|
|
|
+ int count = idCount.getAndIncrement();
|
|
|
+ if (count ==Integer.MAX_VALUE-1) {
|
|
|
+ idCount.set(0);
|
|
|
+ count = idCount.getAndIncrement();
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+ public Integer getStartCount(String key) {
|
|
|
+ RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
|
|
|
+
|
|
|
+ int count = idCount.getAndIncrement();
|
|
|
+ if(count<=1){
|
|
|
+ this.expire(key, CacheKey.DAY1,TimeUnit.DAYS);
|
|
|
+ }
|
|
|
+ if (count ==Integer.MAX_VALUE-1) {
|
|
|
+
|
|
|
+ idCount.set(0);
|
|
|
+ count = idCount.getAndIncrement();
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+ public String getStartNum(Integer num){
|
|
|
+
|
|
|
+ String str=num.toString();
|
|
|
+ int len=str.length();
|
|
|
+ if(str.length()<5){
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ for(int i=0;i<5-len;i++){
|
|
|
+
|
|
|
+ sb.append("0");
|
|
|
+
|
|
|
+ }
|
|
|
+ sb.append(str);
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+ }
|
|
|
+ public String getStartNum(String key){
|
|
|
+ Integer num=getStartCount(key);
|
|
|
+ String str=num.toString();
|
|
|
+ int len=str.length();
|
|
|
+ if(str.length()<5){
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ for(int i=0;i<5-len;i++){
|
|
|
+
|
|
|
+ sb.append("0");
|
|
|
+
|
|
|
+ }
|
|
|
+ sb.append(str);
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public synchronized Integer getSequenceNumber3(String key) {
|
|
|
+ RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
|
|
|
+ int sequenceId = idCount.getAndIncrement();
|
|
|
+ if (sequenceId < 0 || sequenceId >= Integer.MAX_VALUE) {
|
|
|
+ idCount.set(0);
|
|
|
+ sequenceId = idCount.getAndIncrement();
|
|
|
+ return sequenceId;
|
|
|
+ }
|
|
|
+ return sequenceId;
|
|
|
+ }
|
|
|
+ public synchronized Integer getWorkId(String key) {
|
|
|
+ RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
|
|
|
+ int sequenceId = idCount.getAndIncrement();
|
|
|
+ if (sequenceId < 0 || sequenceId >= 31) {
|
|
|
+ idCount.set(0);
|
|
|
+ sequenceId = idCount.getAndIncrement();
|
|
|
+ return sequenceId;
|
|
|
+ }
|
|
|
+ return sequenceId;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 14 * @Description: 初始化自增长值
|
|
|
+ * 15 * @param key key
|
|
|
+ * 16 * @param value 当前值
|
|
|
+ * 17
|
|
|
+ */
|
|
|
+ public void setIncr(String key, int value) {
|
|
|
+ RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
|
|
|
+ counter.set(value);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 14 * @Description: 初始化自增长值
|
|
|
+ * 15 * @param key key
|
|
|
+ * 16 * @param value 当前值
|
|
|
+ * 17
|
|
|
+ */
|
|
|
+ public void setInteger(String key, int value) {
|
|
|
+ RedisAtomicInteger counter = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
|
|
|
+ counter.set(value);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存到hash
|
|
|
+ * @param key
|
|
|
+ * @param hashKey
|
|
|
+ * @param value
|
|
|
+ */
|
|
|
+ public void setHashMap(String key,Object hashKey,Object value){
|
|
|
+ redisTemplate.opsForHash().put(key,hashKey,value);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取hashvalue
|
|
|
+ * @param key
|
|
|
+ * @param hashKey
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Object getHashValue(String key,Object hashKey){
|
|
|
+ return redisTemplate.opsForHash().get(key,hashKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除hash中单个对象
|
|
|
+ * @param key
|
|
|
+ * @param hashKey
|
|
|
+ */
|
|
|
+ public void remove(String key,Object hashKey){
|
|
|
+ redisTemplate.opsForHash().delete(key,hashKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取redisTemplate
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public RedisTemplate getRedisTemplate(){
|
|
|
+ return redisTemplate;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 存储数据或修改数据
|
|
|
+ *
|
|
|
+ * @param modelMap
|
|
|
+ * @param mapName
|
|
|
+ */
|
|
|
+ public void setMap(String mapName, Map<String, Object> modelMap) {
|
|
|
+ HashOperations<String, Object, Object> hps = redisTemplate.opsForHash();
|
|
|
+ hps.putAll(mapName, modelMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取数据Map
|
|
|
+ *
|
|
|
+ * @param mapName
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Map<Object, Object> getMapValue(String mapName) {
|
|
|
+ HashOperations<String, Object, Object> hps = this.redisTemplate.opsForHash();
|
|
|
+ return hps.entries(mapName);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取数据Map size
|
|
|
+ *
|
|
|
+ * @param mapName
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public int getMapSize(String mapName) {
|
|
|
+ HashOperations<String, Object, Object> hps = this.redisTemplate.opsForHash();
|
|
|
+ return hps.entries(mapName).size();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取数据value
|
|
|
+ *
|
|
|
+ * @param mapName
|
|
|
+ * @param hashKey
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Object getValue(String mapName, String hashKey) {
|
|
|
+ HashOperations<String, Object, Object> hps = this.redisTemplate.opsForHash();
|
|
|
+ return hps.get(mapName, hashKey);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量删除缓存数据
|
|
|
+ *
|
|
|
+ * @param keys
|
|
|
+ */
|
|
|
+ public long deleteData(String key,Object ...keys) {
|
|
|
+ // 执行批量删除操作时先序列化template
|
|
|
+ long b= redisTemplate.opsForHash().delete(key,keys);
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void batchCacheMarketInfo(List<Object > dataList, long expire) {
|
|
|
+ //使用pipeline方式
|
|
|
+ redisTemplate.executePipelined(new RedisCallback<List<Object>>() {
|
|
|
+ @Override
|
|
|
+ public List<Object> doInRedis(RedisConnection connection) throws DataAccessException {
|
|
|
+ for (Object marketInfo : dataList) {
|
|
|
+ String key = "";
|
|
|
+ byte[] rawKey = redisTemplate.getKeySerializer().serialize(key);
|
|
|
+ connection.setEx(rawKey, expire, redisTemplate.getValueSerializer().serialize(marketInfo));
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //=========BoundListOperations 用法 End============
|
|
|
+
|
|
|
+}
|