Redis數據結構及Spring-data-redis API使用

一、redis數據類型

Redis目前可以存儲鍵與5種不同數據結構類型之間的映射,分別是:

  • String(字符串)
  • List(列表)
  • Hash(散列)
  • Set(集合)
  • Zset(有序集合)
結構類型 結構存儲的值 結構的讀寫能力
String 可以是字符串、整數或者浮點數 對整個字符串或者字符串的其中一部分執行操作;對象和浮點數執行自增(increment)或者自減(decrement)
List 一個鏈表,鏈表上的每個節點都包含了一個字符串 從鏈表的兩端推入或者彈出元素;根據偏移量對鏈表進行修剪(trim);讀取單個或者多個元素;根據值來查找或者移除元素
Set 包含字符串的無序收集器(unorderedcollection),並且被包含的每個字符串都是獨一無二的、各不相同 添加、獲取、移除單個元素;檢查一個元素是否存在於某個集合中;計算交集、並集、差集;從集合裏賣弄隨機獲取元素
Hash 包含鍵值對的無序散列表 添加、獲取、移除單個鍵值對;獲取所有鍵值對
Zset 字符串成員(member)與浮點數分值(score)之間的有序映射,元素的排列順序由分值的大小決定 添加、獲取、刪除單個元素;根據分值範圍(range)或者成員來獲取元素

二、Spring-data-redis介紹

在Java中通過Jedis來操作Redis,由於Jedis的操作過於底層,或者說封裝得不夠徹底,當我們要存儲一個對象的時候,其實是比較麻煩的,所以使用spring-data-redis越來越流行。Spring-data-redis是Spring-Data項目的一個子項目,就是Spring在Jedis的基礎上封裝的工具,比Jedis更加易用,而且使得操作Redis以更加面向對象的方式。

RedisTemplate中定義了對5種數據結構操作:

  • redisTemplate.opsForValue(),操作string;
  • redisTemplate.opsForHash(),操作hash;
  • redisTemplate.opsForList(),操作list;
  • redisTemplate.opsForSet(),操作set;
  • redisTemplate.opsForZSet(),操作有序set。

三、RedisTemplate通用方法

/**
 * 判斷緩存是否存在
 *
 * @param key
 */
public static boolean exists(String key) {
    return jedisUtil.redisTemplate.hasKey(key);
}

/**
 * 刪除緩存
 *
 * @param key
 * @return if exists 1 else 0
 */
public static long delete(String key) {
    if (exists(key)) {
        jedisUtil.redisTemplate.delete(key);
        return 1;
    }
    return 0;
}

/**
 * 設置Key過期時間
 *
 * @param key
 * @param cacheSeconds
 */
public void setExpireTime(String key, Long cacheSeconds) {
    jedisUtil.redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
}

/**
 * 獲取Key過期時間
 *
 * @param key
 * @return
 */
public static Long getExpireTime(String key) {
    return jedisUtil.redisTemplate.getExpire(key, TimeUnit.SECONDS);
}

四、RedisTemplate操作String類型

public interface ValueOperations<K,V>

/**
 * 設置緩存
 *
 * @param key          鍵
 * @param value        值
 * @param cacheSeconds 超時時間,0爲不超時
 * @return
 */
public static void setStr(String key, String value, Long cacheSeconds) {
    if (cacheSeconds != 0) {
        jedisUtil.redisTemplate.opsForValue().set(key, value, cacheSeconds, TimeUnit.SECONDS);
    } else {
        jedisUtil.redisTemplate.opsForValue().set(key, value);
    }
}

/**
 * 獲取緩存(String)
 *
 * @param key
 * @return
 */
public static String getStr(String key) {
    if (exists(key)) {
        String value = jedisUtil.redisTemplate.opsForValue().get(key).toString();
        return StringUtil.notEmpty(value) && !"nil".equalsIgnoreCase(value) ? value : null;
    }
    return null;
}

/**
 * 設置緩存(T)
 *
 * @param key          鍵
 * @param value        值
 * @param cacheSeconds 超時時間,0爲不超時
 * @return
 */
public static <T> void setValue(String key, T value, Long cacheSeconds) {
    if (cacheSeconds != 0) {
        jedisUtil.redisTemplate.opsForValue().set(key, value, cacheSeconds, TimeUnit.SECONDS);
    } else {
        jedisUtil.redisTemplate.opsForValue().set(key, value);
    }
}

/**
 * 獲取緩存(Object)
 *
 * @param key 鍵
 * @return
 */
public static Object getObject(String key) {
    if (exists(key)) {
        return jedisUtil.redisTemplate.opsForValue().get(key);
    }
    return null;
}

/**
 * 如果鍵不存在則新增
 * 存在則不作修改
 *
 * @param key
 * @param value
 * @param cacheSeconds
 * @return
 */
public static boolean setIfAbsent(String key, String value, Long cacheSeconds) {
    boolean result = false;
    result = jedisUtil.redisTemplate.opsForValue().setIfAbsent(key, value);
    if (cacheSeconds != 0) {
        // 設置key失效時間
        jedisUtil.redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
    }
    return result;
}

/**
 * 獲取原來Key鍵對應的value並重新賦新值
 * 若原來Key鍵不存在則返回null,並且要新建Key再賦值
 *
 * @param key
 * @param value
 * @return
 */
public static String getAndSet(String key, String value, Long cacheSeconds) {
    String res = (String) jedisUtil.redisTemplate.opsForValue().getAndSet(key, value);
    if (cacheSeconds != 0) {
        jedisUtil.redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
    }
    return res;
}

/**
 * 爲多個key分別設置value
 * 已存在的key則覆蓋value
 *
 * @param map
 */
public static void multiSet(Map<String, String> map) {
    jedisUtil.redisTemplate.opsForValue().multiSet(map);
}

/**
 * 以自增形式存儲long類型value
 * 相同的key value值累加
 *
 * @param
 */
public static Long incrLong(String key, Long delta) {
    return jedisUtil.redisTemplate.opsForValue().increment(key, delta);
}

/**
 * 以自增形式存儲doble類型value
 * 相同的key value值累加
 *
 * @param key
 */
public static Double incrDouble(String key, double delta) {
    return jedisUtil.redisTemplate.opsForValue().increment(key, delta);
}

五、RedisTemplate操作List列表

List是簡單的字符串<String>列表,按照插入順序排序,可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)
public interface ListOperations<K,V>,ListOperations專門操作list列表:

/**
 * 存儲整個List<T>
 * 若key相同,則後list加入到前list
 * right批量添加在右邊
 *
 * @param key
 * @param value
 * @param cacheSeconds
 */
public static <T> void setList(String key, List<T> value, Long cacheSeconds) {
    jedisUtil.redisTemplate.opsForList().rightPushAll(key, value);
    if (cacheSeconds != 0) {
        jedisUtil.redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
    }
}

/**
 * 添加單個value到list
 *
 * @param key
 * @param value
 * @param cacheSeconds
 */
public static <T> void setListV(String key, T value, Long cacheSeconds) {
    jedisUtil.redisTemplate.opsForList().rightPush(key, value);
    if (cacheSeconds != 0) {
        jedisUtil.redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
    }
}

/**
 * 返回Key對應的List長度
 * 如果Key不存在,則解釋爲空表,並返回0
 *
 * @param key
 * @return
 */
public static Long getSize(String key) {
    return jedisUtil.redisTemplate.opsForList().size(key);
}

/**
 * 返回指定範圍內的元素
 *
 * @param key
 * @param start 開始 0
 * @param end   結束
 *              0 到 -1 代表全部長度
 */
public static <T> List<T> getList(String key, long start, long end) {
    if (exists(key)) {
        return jedisUtil.redisTemplate.opsForList().range(key, start, end);
    }
    return null;
}

/**
 * 獲取list頭部的第一條value
 *
 * @param key
 */
public static Object leftPopList(String key) {
    if (exists(key)) {
        return jedisUtil.redisTemplate.opsForList().leftPop(key);
    }
    return null;
}

六、RedisTemplate操作Hash散列

Redis的散列可以讓用戶將多個鍵值對存儲到一個Redis鍵裏面
public interface HashOperations<H,HK,HV>,HashOperations提供一系列方法操作hash:

/**
 * 獲取Key鍵對應的哈希HashKey
 *
 * @param key
 * @param hashKey
 * @return
 */
public static Object getHashK(String key, String hashKey) {
    return jedisUtil.redisTemplate.opsForHash().get(key, hashKey);
}

/**
 * 刪除Key鍵對應的哈希HashKey
 *
 * @param key
 * @param hashKey
 * @return
 */
public static Long delHashK(String key, String hashKey) {
    return jedisUtil.redisTemplate.opsForHash().delete(key, hashKey);
}

/**
 * 判斷Key鍵對應的哈希HashKey是否存在
 *
 * @param key
 * @param hashKey
 * @return
 */
public static boolean hashKey(String key, String hashKey) {
    return jedisUtil.redisTemplate.opsForHash().hasKey(key, hashKey);
}

/**
 * 通過給定的delta增加散列HashKey的值(Long)
 *
 * @param key
 * @param hashKey
 * @param delta
 */
public static Long incrHashLong(String key, String hashKey, long delta) {
    return jedisUtil.redisTemplate.opsForHash().increment(key, hashKey, delta);
}

/**
 * 通過給定的delta增加散列HashKey的值(Double)
 *
 * @param key
 * @param hashKey
 * @param delta
 * @return
 */
public static Double incrHashDouble(String key, String hashKey, Double delta) {
    return jedisUtil.redisTemplate.opsForHash().increment(key, hashKey, delta);
}


/**
 * 存儲Key鍵 - HashKey - Map<String, T>
 *
 * @param key
 * @param hashKey
 * @param value
 * @param <T>
 */
public static <T> void setHKMap(String key, String hashKey, Map<String, T> value) {
    jedisUtil.redisTemplate.opsForHash().put(key, hashKey, value);
}


/**
 * 獲取HashKey - Map<String, Object>
 *
 * @param key
 * @return
 */
public static Map<String, Map<String, Object>> getHKMap(String key) {
    Map<String, Map<String, Object>> value = null;
    if (exists(key)) {
        jedisUtil.redisTemplate.opsForHash().entries(key);
    }
    return value;
}

/**
 * 存儲Key鍵 - HashKey - List<T>
 *
 * @param key
 * @param hashKey
 * @param value
 * @param <T>
 */
public static <T> void setHKList(String key, String hashKey, List<T> value) {
    jedisUtil.redisTemplate.opsForHash().put(key, hashKey, value);
}

/**
 * 存儲Key鍵 - 所有(HashKey - List<T>)Map集合
 *
 * @param key
 * @param value
 * @param cacheSeconds
 * @param <T>
 */
public static <T> void setMapListAll(String key, Map<String, List<T>> value, Long cacheSeconds) {
    jedisUtil.redisTemplate.opsForHash().putAll(key, value);
    if (cacheSeconds != 0) {
        jedisUtil.redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
    }
}

/**
 * 獲取HashKey - List<T>
 *
 * @param key
 * @return
 */
public static <T> Map<String, List<T>> getHKList(String key) {
    Map<String, List<T>> value = null;
    if (exists(key)) {
        value = jedisUtil.redisTemplate.opsForHash().entries(key);
    }
    return value;
}

/**
 * 存儲Key鍵 - HashKey - T value
 *
 * @param key
 * @param hashKey
 * @param value
 * @param <T>
 */
public static <T> void setHKObject(String key, String hashKey, T value) {
    jedisUtil.redisTemplate.opsForHash().put(key, hashKey, value);
}

/**
 * 存儲Key鍵 - 所以 (HashKey - T value)Map集合
 *
 * @param key
 * @param value
 * @param cacheSeconds
 * @param <T>
 */
public static <T> void setHKObjectAll(String key, Map<String, T> value, Long cacheSeconds) {
    jedisUtil.redisTemplate.opsForHash().putAll(key, value);
    if (cacheSeconds != 0) {
        jedisUtil.redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
    }
}

/**
 * 獲取HashKey - T
 *
 * @param key
 * @param <T>
 * @return
 */
public static <T> Map<String, T> getHKObject(String key) {
    Map<String, T> value = null;
    if (exists(key)) {
        value = jedisUtil.redisTemplate.opsForHash().entries(key);
    }
    return value;
}

七、RedisTemplate操作Set集合

Redis的Set是String類型的無序集合,集合成員是唯一的,這就意味着集合中不能出現重複的數據。Set是通過哈希表實現的,所以添加,刪除,查找的複雜度都是O(1)。
public interface SetOperations<K,V>,SetOperations提供了對無序集合的一系列操作:

/**
 * 無序集合中添加元素,返回添加的個數
 *
 * @param strings
 * @return
 */
public static Long addSet(String key, String[] strings) {
    return jedisUtil.redisTemplate.opsForSet().add(key, strings);
}

/**
 * 返回無序集合的大小長度
 *
 * @param key
 * @return
 */
public static Long getSetSize(String key) {
    return jedisUtil.redisTemplate.opsForSet().size(key);
}

/**
 * 返回集合中的所有成員
 *
 * @param key
 * @param <T>
 * @return
 */
public static <T> Set<T> getMembers(String key) {
    return jedisUtil.redisTemplate.opsForSet().members(key);
}

/**
 * 隨機獲取Key對應無序集合中的一個元素
 *
 * @param key
 * @return
 */
public static Object getRanMembers(String key) {
    return jedisUtil.redisTemplate.opsForSet().randomMember(key);
}

/**
 * 判斷value是否是對應集合的成員
 *
 * @param key
 * @param value
 * @return
 */
public static Boolean isMembers(String key, Object value) {
    return jedisUtil.redisTemplate.opsForSet().isMember(key, value);
}

/**
 * 移除集合中多個成員,並返回刪除個數
 *
 * @param key
 * @param strings
 * @return
 */
public static Long removeMembers(String key, String[] strings) {
    return jedisUtil.redisTemplate.opsForSet().remove(key, strings);
}

/**
 * 將元素value從一個集合移動到另一個集合
 *
 * @param startKey
 * @param endKey
 * @param value
 * @return
 */
public static Boolean moveSet(String startKey, String endKey, Object value) {
    return jedisUtil.redisTemplate.opsForSet().move(startKey, value, endKey);
}

八、RedisTemplate操作Zset集合

Redis 有序集合Zset和無序集合Set一樣也是string類型元素的集合,且不允許重複的成員。不同的是每個元素都會關聯一個double類型的分數,Redis正是通過分數來爲集合中的成員進行從小到大的排序。有序集合的成員是唯一的,但分數(score)卻可以重複。
public interface ZSetOperations<K,V>

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章