content: package com.ctg.test.config;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.data.redis.core.RedisTemplate;
  import org.springframework.data.redis.core.StringRedisTemplate;
  import org.springframework.stereotype.Component;
  import org.springframework.util.CollectionUtils;
  import org.springframework.util.StringUtils;
  
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.concurrent.TimeUnit;
  
  
  /**
   * @Description: TODO
   * @Author: yanhonghai
   * @Date: 2018/9/29 15:32
   */
  @Component
  public class RedisUtil {
      @Autowired
      private RedisTemplate<String, Object> redisTemplate;
      @Autowired
      private StringRedisTemplate stringRedisTemplate;
  
      //=============================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(CollectionUtils.arrayToList(key));
              }
          }
      }
  
      /**
       * 批量删除<br>
       * （该操作会执行模糊查询，请尽量不要使用，以免影响性能或误删）
       * @param pattern
       */
      public void batchDel(String... pattern){
          for (String kp : pattern) {
              redisTemplate.delete(redisTemplate.keys(kp + "*"));
          }
      }
  
      //============================String=============================
      /**
       * 普通缓存获取
       * @param key 键
       * @return 值
       */
      public Object get(String key){
          return key==null?null:redisTemplate.opsForValue().get(key);
      }
  
      /**
       * 取得缓存（int型）
       * @param key
       * @return
       */
      public Integer getInt(String key){
          String value = stringRedisTemplate.boundValueOps(key).get();
          if(!StringUtils.isEmpty(value)){
              return Integer.valueOf(value);
          }
          return null;
      }
  
      /**
       * 取得缓存（字符串类型）
       * @param key
       * @return
       */
      public String getStr(String key){
          return stringRedisTemplate.boundValueOps(key).get();
      }
  
      /**
       * 取得缓存（字符串类型）
       * @param key
       * @return
       */
      public String getStr(String key, boolean retain){
          String value = stringRedisTemplate.boundValueOps(key).get();
          if(!retain){
              redisTemplate.delete(key);
          }
          return value;
      }
  
      /**
       * 获取缓存<br>
       * 注：基本数据类型(Character除外)，请直接使用get(String key, Class<T> clazz)取值
       * @param key
       * @return
       */
      public Object getObj(String key){
          return redisTemplate.boundValueOps(key).get();
      }
  
      /**
       * 获取缓存<br>
       * 注：java 8种基本类型的数据请直接使用get(String key, Class<T> clazz)取值
       * @param key
       * @param retain    是否保留
       * @return
       */
      public Object getObj(String key, boolean retain){
          Object obj = redisTemplate.boundValueOps(key).get();
          if(!retain){
              redisTemplate.delete(key);
          }
          return obj;
      }
  
      /**
       * 获取缓存<br>
       * 注：该方法暂不支持Character数据类型
       * @param key   key
       * @param clazz 类型
       * @return
       */
      @SuppressWarnings("unchecked")
      public <T> T get(String key, Class<T> clazz) {
          return (T)redisTemplate.boundValueOps(key).get();
      }
  
  
      /**
       * 普通缓存放入
       * @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;
          }
      }
  
      /**
       * 将value对象写入缓存
       * @param key
       * @param value
       * @param time 失效时间(秒)
       */
      public void push(String key,Object value, long time){
          if(value.getClass().equals(String.class)){
              stringRedisTemplate.opsForValue().set(key, value.toString());
          }else if(value.getClass().equals(Integer.class)){
              stringRedisTemplate.opsForValue().set(key, value.toString());
          }else if(value.getClass().equals(Double.class)){
              stringRedisTemplate.opsForValue().set(key, value.toString());
          }else if(value.getClass().equals(Float.class)){
              stringRedisTemplate.opsForValue().set(key, value.toString());
          }else if(value.getClass().equals(Short.class)){
              stringRedisTemplate.opsForValue().set(key, value.toString());
          }else if(value.getClass().equals(Long.class)){
              stringRedisTemplate.opsForValue().set(key, value.toString());
          }else if(value.getClass().equals(Boolean.class)){
              stringRedisTemplate.opsForValue().set(key, value.toString());
          }else{
              redisTemplate.opsForValue().set(key, value);
          }
          if(time > 0){
              redisTemplate.expire(key, time, TimeUnit.SECONDS);
          }
      }
  
      /**
       * 普通缓存放入并设置时间
       * @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 by 要增加几(大于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 by 要减少几(小于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;
          }
      }
  
      /**
       * 向一张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;
          }
      }
  
      /**
       * 移除值为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 值
       * @param time 时间(秒)
       * @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 值
       * @param time 时间(秒)
       * @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;
          }
      }
  }
  