1. 程式人生 > 資料庫 >SpringBoot使用RedisTemplate簡單操作Redis的五種資料型別

SpringBoot使用RedisTemplate簡單操作Redis的五種資料型別

一、介紹

Spring 封裝了 RedisTemplate 來操作 Redis,它支援所有的 Redis 原生的 API。在 RedisTemplate 中定義了對5種資料結構的操作方法。

opsForValue():操作字串。
opsForList():操作列表。
opsForHash():操作雜湊。
opsForSet():操作集合。
opsForZSet():操作有序集合。

引入依賴

	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
    </parent>


  	<!--pringDataRedis-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-redis</artifactId>
     </dependency>

配置檔案

server:
  port: 8080
spring:
  application:
    name: redisTemplate
  #redis預設配置
  redis:
    host: 116.62.13.104

Demo結構

在這裡插入圖片描述
本Demo在測試類中操作Redis的五種資料型別

Bug

在這裡插入圖片描述

解決方法:

    /**
     * 指定序列化方式
     * 如果不指定序列化方式
     * String型別存入到Redis中會  : \xAC\xED\x00\x05t\x00\x09Stringkey
     */
    @PostConstruct
    public void init() {
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);
        redisTemplate.setValueSerializer(redisSerializer);
        redisTemplate.setHashKeySerializer(redisSerializer);
        redisTemplate.setHashValueSerializer(redisSerializer);
    }

在這裡插入圖片描述

在這裡插入圖片描述

操作五種資料型別

1.String型別

  /**
     * redisTemplate.opsForValue()   操作String型別   Key-Value 鍵值對
     * 使用set(K key, V value)        存入
     *
     * get(K key)                     取出
     *
     * set(K key, V value, long timeout, TimeUnit unit) 設定失效時間
     *
     * redisTemplate.opsForValue().getAndSet(K key, V value);  獲得舊值並重新放入新值
     */
    @Test
    public void test1(){
        init();
        redisTemplate.opsForValue().set("Stringkey1","StringValue1");
        redisTemplate.opsForValue().set("Stringkey2","StringValue2",120, TimeUnit.SECONDS);

        System.out.println(redisTemplate.opsForValue().get("Stringkey1"));
        System.out.println(redisTemplate.opsForValue().get("Stringkey2"));
        redisTemplate.opsForValue().getAndSet("Stringkey1","StringValue11");
        System.out.println(redisTemplate.opsForValue().get("Stringkey1"));
    }

在這裡插入圖片描述

2.Hash型別

Redis 中的 hash(雜湊)是一個 string 型別的 fieldvalue 的對映表,hash 特別適合用於儲存物件。value 中存放的是結構化的物件。利用這樣資料結果,可以方便地操作其中的某個欄位。比如在“單點登入”時,可以用這種資料結構儲存使用者資訊。以 CookieId 作為 key,設定30分鐘為快取過期時間,能很好地模擬出類似 Session 的效果。

在這裡插入圖片描述

    /**
     * redisTemplate.opsForHash()操作Hash結構
     *
     * putAll(K key,Map map)直接Map存入
     * entries(K key)       取出
     * void put(H key, HK hashKey, HV value)   存入單個欄位
     *
     * HV get(H key, Object hashKey) 獲得Hash型別的單個欄位
     */
    @Test
    public void test3(){
        init();
        HashMap<String, String> map = new HashMap<>();
        map.put("id","1");
        map.put("name","LiuShihao");
        map.put("age","24");
        map.put("job","Police");

//        redisTemplate.opsForHash().putAll("userHash",map);
        System.out.println(redisTemplate.opsForHash().entries("userHash"));


//        redisTemplate.opsForHash().put("userHash2","id","1");
//        redisTemplate.opsForHash().put("userHash2","name","aaa");
//        redisTemplate.opsForHash().put("userHash2","age","24");
//        redisTemplate.opsForHash().put("userHash2","job","美團外賣");

        System.out.println(redisTemplate.opsForHash().get("userHash2","id"));
        System.out.println(redisTemplate.opsForHash().get("userHash2","name"));
        System.out.println(redisTemplate.opsForHash().get("userHash2","age"));
        System.out.println(redisTemplate.opsForHash().get("userHash2","job"));

        //獲取整個Hash型別的key
        System.out.println(redisTemplate.opsForHash().keys("userHash2"));
        //獲取整個Hash型別的value
        System.out.println(redisTemplate.opsForHash().values("userHash2"));

    }

3.List型別

Redis列表是簡單的字串列表,按照插入順序排序。可以新增一個元素到列表的頭部(左邊)或尾部(右邊)。

使用list資料結構,可以做簡單的訊息佇列的功能。還可以利用 Irange 命令,做基於Reids的分頁功能,效能極佳。

在這裡插入圖片描述

/**
     * redisTemplate.opsForList()  操作List型別
     * leftPushAll:向一個key中直接插入字元陣列
     * range:獲得一個list中的 所有欄位資訊  第一個索引是0, 最後一個索引是-1
     * rightPush:向一個List中插入單個欄位
     * index: 根據索引獲得list中的欄位
     *
     * leftPop方法:彈出最左邊的元素,彈出之後該值在列表中將不復存在。
     *
     * rightPop方法:彈出最右邊的元素,彈出之後該值在列表中將不復存在。具體用法見以下程式碼:
     */
    @Test
    public void test2(){
        init();
        String[] user1 = new String[]{"1","zs","19","程式設計師"};
        //向一個key中直接插入字元陣列
        redisTemplate.opsForList().leftPushAll("user1-leftPushAll",user1);
        redisTemplate.opsForList().rightPushAll("user1-rightPushAll",user1);
        // 獲得一個list中的 所有欄位資訊  第一個索引是0, 最後一個索引是-1
        System.out.println(redisTemplate.opsForList().range("user1-leftPushAll",0,-1));
        System.out.println(redisTemplate.opsForList().range("user1-rightPushAll",0,-1));

        //向一個key中插入單個欄位
        redisTemplate.opsForList().rightPush("user2-rightPush","1");
        redisTemplate.opsForList().rightPush("user2-rightPush","ls");
        redisTemplate.opsForList().rightPush("user2-rightPush","20");
        redisTemplate.opsForList().rightPush("user2-rightPush","教師");

        // 根據索引獲得list中的一個key中的第幾個欄位
        System.out.println(redisTemplate.opsForList().index("user2-rightPush",0));
        System.out.println(redisTemplate.opsForList().index("user2-rightPush",1));
        System.out.println(redisTemplate.opsForList().index("user2-rightPush",2));
        System.out.println(redisTemplate.opsForList().index("user2-rightPush",3));

        String[] user3 = new String[]{"3","ww","28","警察"} ;
        redisTemplate.opsForList().rightPushAll("user3",user3);
        System.out.println(redisTemplate.opsForList().range("user3",0,-1));
        //彈出最右邊的元素,彈出之後該值在列表中將不復存在
        System.out.println(redisTemplate.opsForList().rightPop("user3"));
        System.out.println(redisTemplate.opsForList().range("user3",0,-1));

    }

4.Set型別

set 是存放不重複值的集合。利用 set 可以做全域性去重複的功能。還可以進行交集、並集、差集等操作,也可用來實現計算共同喜好、全部的喜好、自己獨有的喜好等功能。

Redis 的 set 是 string 型別的無序集合,通過散列表實現。
在這裡插入圖片描述

    /**
     * 使用redisTemplate.opsForSet() 操作Set型別
     * add方法:在無序集合中新增元素,返回添加個數;如果存在重複的則不進行新增。
     *
     * members方法:返回集合中的所有成員。
     *
     * Long remove(K key, Object... values)  移除集合中一個或多個成員。
     *
     * scan   遍歷Set集合
     *
     * Set<V> intersect(K key1, K key2)方法、Long intersectAndStore(K key1, K key2, K destKey)方法:交集。
     *
     * Set<V> union(K key1, K key2)方法、Long unionAndStore(K key1, K key2, K destKey)方法:並集。
     *
     * Set<V> difference(K key1, K key2)方法、Long differenceAndStore(K key1, K key2, K destKey)方法:差集。
     */
    @Test
    public void test4(){
        init();
        String[] citys = new String[] {"北京","上海","廣州","深圳"};
//        redisTemplate.opsForSet().add("citySet",citys);
        System.out.println(redisTemplate.opsForSet().members("citySet"));
//        redisTemplate.opsForSet().add("citySet","鄭州","北京","上海");
//        System.out.println(redisTemplate.opsForSet().members("citySet"));
        //remove  移除一個或多個元素
//        System.out.println(redisTemplate.opsForSet().remove("citySet","廣州"));
//        System.out.println(redisTemplate.opsForSet().members("citySet"));
        // 遍歷Set
        Cursor citySet = redisTemplate.opsForSet().scan("citySet", ScanOptions.NONE);
        while(citySet.hasNext())
        {
            System.out.println(citySet.next());
        }

        redisTemplate.opsForSet().add("CitysSet1","北京","武漢","石家莊","鄭州","西安","濟南");
        redisTemplate.opsForSet().add("CitysSet2","上海","浙江","南京","鄭州","香港","北京");

        //交集
        redisTemplate.opsForSet().intersectAndStore("CitysSet1","CitysSet2","CitysSetIntersectAndStore");
        //並集
        redisTemplate.opsForSet().unionAndStore("CitysSet1","CitysSet2","CitysSetUnionAndStore");
        //差集  的意思是 對CitysSet1求CitysSet2的差集   返回的結果:[石家莊, 西安, 濟南, 武漢]   代表的是1中有2中沒有的元素
        redisTemplate.opsForSet().differenceAndStore("CitysSet1","CitysSet2","CitysSetDifferenceAndStore");

        System.out.println(redisTemplate.opsForSet().members("CitysSetIntersectAndStore"));
        System.out.println(redisTemplate.opsForSet().members("CitysSetUnionAndStore"));
        System.out.println(redisTemplate.opsForSet().members("CitysSetDifferenceAndStore"));

    }

5.ZSet型別

zset(Sorted Set 有序集合)也是 string 型別元素的集合且不允許重複的成員。每個元素都會關聯一個 double 型別的分數。可以通過分數將該集合中的成員從小到大進行排序。

zset 的成員是唯一的,但權重引數分數(score)卻可以重複。集合中的元素能夠按 score 進行排列。它可以用來做排行榜應用、取TOP/N、延時任務、範圍查詢等。

在這裡插入圖片描述
第一種新增方式:
在這裡插入圖片描述
第二種新增方式:
在這裡插入圖片描述

 /**
     * zset(Sorted Set 有序集合)也是 string 型別元素的集合,且不允許重複的成員。每個元素都會關聯一個 double 型別的分數。可以通過分數將該集合中的成員從小到大進行排序。
     *
     * zset 的成員是唯一的,但權重引數分數(score)卻可以重複。集合中的元素能夠按 score 進行排列。它可以用來做排行榜應用、取TOP/N、延時任務、範圍查詢等。
     *
     * 使用redisTemplate.opsForZSet() 操作ZSet集合
     * Boolean add(K var1, V var2, double var3);
     * Long add(K key, Set<ZSetOperations.TypedTuple<V>> tuples)            增加一個有序集合
     *
     * Long remove(K key, Object... values)    從有序集合中移除一個或者多個元素
     *
     * Set<V> range(K KET, long var2, long var4);   檢視ZSet集合中的元素
     *
     * Long rank(K key, Object value)   返回有序集中指定成員的排名,其中有序整合員按分數值遞增(從小到大)順序排列
     *
     * rank  返回有序集中指定成員的排名,    其中有序整合員按分數值遞增(從小到大)順序排列
     *
     * range方法:通過索引區間返回有序集合成指定區間內的成員,其中有序整合員按分數值遞增(從小到大)順序排列。
     *
     * rangeByScore方法:通過分數區間返回有序集合成指定區間內的成員,其中有序整合員按分數值遞增(從小到大)順序排列。
     *
     * count方法:通過分數返回有序集合指定區間內的成員個數。
     *
     * size方法:獲取有序集合的成員數。
     */
    @Test
    public void test5(){

        ZSetOperations.TypedTuple<String> objectTypedTuple1 = new DefaultTypedTuple<>("肖申克的救贖",9.7);
        ZSetOperations.TypedTuple<String> objectTypedTuple2 = new DefaultTypedTuple<>("霸王別姬",9.6);
        ZSetOperations.TypedTuple<String> objectTypedTuple3 = new DefaultTypedTuple<>("阿甘正傳",9.5);
        ZSetOperations.TypedTuple<String> objectTypedTuple4 = new DefaultTypedTuple<>("這個殺手不太冷",9.4);
        ZSetOperations.TypedTuple<String> objectTypedTuple5 = new DefaultTypedTuple<>("冷血狂宴 / 爵跡2",4.0);

        Set<ZSetOperations.TypedTuple<String>> movie = new HashSet<ZSetOperations.TypedTuple<String>>();
        movie.add(objectTypedTuple1);
        movie.add(objectTypedTuple2);
        movie.add(objectTypedTuple3);
        movie.add(objectTypedTuple4);
        movie.add(objectTypedTuple5);

        redisTemplate.opsForZSet().add("movie",movie);
        //通過索引區間返回有序集合成指定區間內的成員,其中有序整合員按分數值遞增(從小到大)順序排列。
        System.out.println(redisTemplate.opsForZSet().range("movie",0,-1));

        redisTemplate.opsForZSet().add("StudentZSet","99",9.9);
        redisTemplate.opsForZSet().add("StudentZSet","80",8.0);
        redisTemplate.opsForZSet().add("StudentZSet","69",6.9);
        redisTemplate.opsForZSet().add("StudentZSet","52",5.4);
        redisTemplate.opsForZSet().add("StudentZSet","32",3.4);
        redisTemplate.opsForZSet().add("StudentZSet","23",1.9);

        System.out.println(redisTemplate.opsForZSet().range("StudentZSet",0,-1));
        // 移除ZSet中的一個或多個元素
        redisTemplate.opsForZSet().remove("StudentZSet","69");
        System.out.println("移除ZSet中的一個或多個元素:"+redisTemplate.opsForZSet().range("StudentZSet",0,-1));
        //返回有序集中指定成員的排名,    其中有序整合員按分數值遞增(從小到大)順序排列
        System.out.println("返回有序集中指定成員的排名:"+redisTemplate.opsForZSet().rank("movie", "阿甘正傳"));

        //通過分數區間返回有序集合成指定區間內的成員,其中有序整合員按分數值遞增(從小到大)順序排列。
        System.out.println("通過分數區間返回有序集合成指定區間內的成員:"+redisTemplate.opsForZSet().rangeByScore("StudentZSet", 3, 8));

        System.out.println("分數在0至8區間內的成員個數:" + redisTemplate.opsForZSet().count("StudentZSet", 3, 8));
        System.out.println("movie有序集合的成員數:" + redisTemplate.opsForZSet().size("movie"));

        System.out.println("獲取指定成員的score值:" + redisTemplate.opsForZSet().score("movie", "這個殺手不太冷"));

        // 遍歷 zset
        Cursor<ZSetOperations.TypedTuple<Object>> cursor = redisTemplate.opsForZSet().scan("movie",ScanOptions.NONE);
        while (cursor.hasNext()){
            ZSetOperations.TypedTuple<Object> next = cursor.next();
        //System.out.println(next); // 列印的物件地址 org.springframework.data.redis.core.DefaultTypedTuple@35698b75
            System.out.println(next.getValue() + " 的分數值:" + next.getScore());

        }

    }