如何使用RedisTemplate訪問Redis數據結構之字符串操作


Redis 數據結構簡介

Redis 可以存儲鍵與5種不同數據結構類型之間的映射,這5種數據結構類型分別為String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。

下面來對這5種數據結構類型作簡單的介紹:

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

Redis 5種數據結構的概念大致介紹到這邊,下面將結合Spring封裝的RedisTemplate來對這5種數據結構的運用進行演示

RedisTemplate介紹

spring 封裝了 RedisTemplate 對象來進行對redis的各種操作,它支持所有的 redis 原生的 api。

RedisTemplate在spring代碼中的結構如下:

 

org.springframework.data.redis.core
Class RedisTemplate<K,V>
java.lang.Object
    org.springframework.data.redis.core.RedisAccessor
        org.springframework.data.redis.core.RedisTemplate<K,V>

 

Type Parameters:
K

  • the Redis key type against which the template works (usually a String)
    模板中的Redis key的類型(通常為String)如:RedisTemplate<String, Object>
    注意:如果沒特殊情況,切勿定義成RedisTemplate<Object, Object>,否則根據里氏替換原則,使用的時候會造成類型錯誤 。
    V
  • the Redis value type against which the template works
    模板中的Redis value的類型

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

 

redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set

 

StringRedisTemplate與RedisTemplate

  • 兩者的關系是StringRedisTemplate繼承RedisTemplate。

  • 兩者的數據是不共通的;也就是說StringRedisTemplate只能管理StringRedisTemplate里面的數據,RedisTemplate只能管理RedisTemplate中的數據。

  • SDR默認采用的序列化策略有兩種,一種是String的序列化策略,一種是JDK的序列化策略。

    StringRedisTemplate默認采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。

    RedisTemplate默認采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

RedisTemplate配置如下:

 

@Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
    {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

 

Redis的String數據結構 (推薦使用StringRedisTemplate)

注意:如果使用RedisTemplate需要更改序列化方式

 

RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringSerializer );
        template.setValueSerializer(stringSerializer );
        template.setHashKeySerializer(stringSerializer );
        template.setHashValueSerializer(stringSerializer );

 

public interface ValueOperations<K,V>
Redis operations for simple (or in Redis terminology 'string') values.
ValueOperations可以對String數據結構進行操作:

  • set void set(K key, V value);

 

使用:redisTemplate.opsForValue().set("name","tom");
結果:redisTemplate.opsForValue().get("name")  輸出結果為tom

 

  • set void set(K key, V value, long timeout, TimeUnit unit);

 

使用:redisTemplate.opsForValue().set("name","tom",10, TimeUnit.SECONDS);
結果:redisTemplate.opsForValue().get("name")由於設置的是10秒失效,十秒之內查詢有結果,十秒之后返回為null

 

  set void set(K key, V value, long offset);該方法是用 value 參數覆寫(overwrite)給定 key 所儲存的字符串值,從偏移量 offset 開始

 

使用:template.opsForValue().set("key","hello world");
        template.opsForValue().set("key","redis", 6);
        System.out.println("***************"+template.opsForValue().get("key"));
結果:***************hello redis

 

  • setIfAbsent Boolean setIfAbsent(K key, V value);

 

使用:System.out.println(template.opsForValue().setIfAbsent("multi1","multi1"));//false  multi1之前已經存在
        System.out.println(template.opsForValue().setIfAbsent("multi111","multi111"));//true  multi111之前不存在
結果:false
true
  • multiSet void multiSet(Map<? extends K, ? extends V> m);為多個鍵分別設置它們的值

使用:Map<String,String> maps = new HashMap<String, String>();
        maps.put("multi1","multi1");
        maps.put("multi2","multi2");
        maps.put("multi3","multi3");
        template.opsForValue().multiSet(maps);
        List<String> keys = new ArrayList<String>();
        keys.add("multi1");
        keys.add("multi2");
        keys.add("multi3");
        System.out.println(template.opsForValue().multiGet(keys));
結果:[multi1, multi2, multi3]
  • multiSetIfAbsent Boolean multiSetIfAbsent(Map<? extends K, ? extends V> m);為多個鍵分別設置它們的值,如果存在則返回false,不存在返回true

使用:Map<String,String> maps = new HashMap<String, String>();
        maps.put("multi11","multi11");
        maps.put("multi22","multi22");
        maps.put("multi33","multi33");
        Map<String,String> maps2 = new HashMap<String, String>();
        maps2.put("multi1","multi1");
        maps2.put("multi2","multi2");
        maps2.put("multi3","multi3");
        System.out.println(template.opsForValue().multiSetIfAbsent(maps));
        System.out.println(template.opsForValue().multiSetIfAbsent(maps2));
結果:true
false

 

  • get V get(Object key);

 

使用:template.opsForValue().set("key","hello world");
        System.out.println("***************"+template.opsForValue().get("key"));
結果:***************hello world
  • getAndSet V getAndSet(K key, V value);設置鍵的字符串值並返回其舊值

使用:template.opsForValue().set("getSetTest","test");
        System.out.println(template.opsForValue().getAndSet("getSetTest","test2"));
結果:test
  • multiGet List<V> multiGet(Collection<K> keys);為多個鍵分別取出它們的值

使用:Map<String,String> maps = new HashMap<String, String>();
        maps.put("multi1","multi1");
        maps.put("multi2","multi2");
        maps.put("multi3","multi3");
        template.opsForValue().multiSet(maps);
        List<String> keys = new ArrayList<String>();
        keys.add("multi1");
        keys.add("multi2");
        keys.add("multi3");
        System.out.println(template.opsForValue().multiGet(keys));
結果:[multi1, multi2, multi3]
  • increment Long increment(K key, long delta);支持整數

使用:template.opsForValue().increment("increlong",1);
        System.out.println("***************"+template.opsForValue().get("increlong"));
結果:***************1
  • increment Double increment(K key, double delta);也支持浮點數

使用:template.opsForValue().increment("increlong",1.2);
        System.out.println("***************"+template.opsForValue().get("increlong"));
結果:***************2.2
  • append Integer append(K key, String value);如果key已經存在並且是一個字符串,則該命令將該值追加到字符串的末尾。
  • 如果鍵不存在,則它被創建並設置為空字符串,因此APPEND在這種特殊情況下將類似於SET。

使用:template.opsForValue().append("appendTest","Hello");
        System.out.println(template.opsForValue().get("appendTest"));
        template.opsForValue().append("appendTest","world");
        System.out.println(template.opsForValue().get("appendTest"));
結果:Hello
        Helloworld
  • get String get(K key, long start, long end);截取key所對應的value字符串

使用:appendTest對應的value為Helloworld
System.out.println("*********"+template.opsForValue().get("appendTest",0,5));
結果:*********Hellow
使用:System.out.println("*********"+template.opsForValue().get("appendTest",0,-1));
結果:*********Helloworld
使用:System.out.println("*********"+template.opsForValue().get("appendTest",-3,-1));
結果:*********rld
  • size Long size(K key);返回key所對應的value值得長度

使用:template.opsForValue().set("key","hello world");
    System.out.println("***************"+template.opsForValue().size("key"));
結果:***************11
  • setBit Boolean setBit(K key, long offset, boolean value);對 key 所儲存的字符串值,設置或清除指定偏移量上的位(bit)
    key鍵對應的值value對應的ascii碼,在offset的位置(從左向右數)變為value

使用:template.opsForValue().set("bitTest","a");
        // 'a' 的ASCII碼是 97。轉換為二進制是:01100001
        // 'b' 的ASCII碼是 98  轉換為二進制是:01100010
        // 'c' 的ASCII碼是 99  轉換為二進制是:01100011
        //因為二進制只有0和1,在setbit中true為1,false為0,因此我要變為'b'的話第六位設置為1,第七位設置為0
        template.opsForValue().setBit("bitTest",6, true);
        template.opsForValue().setBit("bitTest",7, false);
        System.out.println(template.opsForValue().get("bitTest"));
結果:b
  • getBit Boolean getBit(K key, long offset);獲取鍵對應值的ascii碼的在offset處位值

使用:System.out.println(template.opsForValue().getBit("bitTest",7));
結果:false

作者:DreamerRzc
鏈接:https://www.jianshu.com/p/7bf5dc61ca06
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM