RedisTemplate操作命令 - Hash


 

Hash操作


 

* 看別人的總沒有自己實操來的印象深刻

redis的五大數據類型 字符串、列表、集合、有序集合、哈希

redis的哈希類型指的是鍵值本身又是一個鍵值對結構:

如:vaule = {{key1,value1},{key2,value2}...{keyn,valuen}}

相對於java可以理解為map:Key=>(Map<HK,HV>)

 

哈希類型的內部編碼有兩種:

ziplist(壓縮列表):當哈希類型元素個數小於hash-max-ziplist-entries配置(默認512個)、同時所有值都小於hash-max-ziplist-value配置(默認64字節)時,Redis會使用ziplist作為哈希的內部實現,ziplist使用更加緊湊的結構實現多個元素的連續存儲,所以在節省內存方面比hashtable更加優秀。

hashtable(哈希表):當哈希類型無法滿足ziplist的條件時,Redis會使用hashtable作為哈希的內部實現,因為此時ziplist的讀寫效率會下降,而hashtable的讀寫時間復雜度為O(1)。

 

在redis開發與運維中的圖解:

 

redis對哈希的命令在redisTemplate中都有映射,見下方表:


 

redisTemplate

//以下表格使用hash代替redisTemplate.opsForHash() : HashOperations hash = redisTemplate.opsForHash();

命令 操作 返回值
hash.delete(H key, Object... hashKeys) 刪除,可以傳入多個map的key【hdel】 Long
hash.hasKey(key, hashKey) 查看hash中的某個hashKey是否存在【hexists】 Boolean
hash.get(key, hashKey) 獲取值【hget】 Object(HV 泛型約束對象)
hash.multiGet(H key, Collection<HK> hashKeys) 批量獲取集合中的key對應的值【hmget】 List<HV>
hash.increment(H key, HK hashKey, long delta) 對值進行+(delta值)操作【】 Long
hash.increment(H key, HK hashKey, double delta) ~ double
hash.keys(key) 返回map內hashKey的集合【hkeys】 Set<HK>
hash.lengthOfValue(H key, HK hashKey) 返回查詢鍵關聯的值的長度,為null則返回0【hstrlen】 Long
hash.size(H key) 獲取hashKey的個數【hlen】 Long
hash.putAll(H key, Map<? extends HK, ? extends HV> m) 相當於map的putAll【hmset】 void
hash.put(H key, HK hashKey, HV value) 設置值,添加hashKey-value,hashKay相當於map的key 【hset】 void
hash.putIfAbsent(H key, HK hashKey, HV value) 僅當hashKey不存在時設置值 Boolean
hash.values(key) 返回value的集合【hvals】 List<HV>
hase.entries(H key) 獲取map【hgetall】 Map<HK, HV>
hash.scan(H key, ScanOptions options) 基於游標的迭代查詢【hscan】 Cursor<Map.Entry<HK, HV>>(返回的Cursor要手動關閉,見下面示例2)
hash.getOperations() 返回RedisOperation,它就是redis操作的接口 RedisOperations<H, ?>

 

 對於命令的時間復雜度見下表:

示例測試操作1:

     //key
        String k = "phoneMap";
        //map的key
        String hashKey = "13838383838";

        Map<String, String> phoneMap = new HashMap<>();
        phoneMap.put("13838383839","1");
        phoneMap.put(hashKey,"2");

        //添加map
        //redisTemplate.opsForHash().putAll(k, phoneMap);

        //在key的value中添加單個hash值
        redisTemplate.opsForHash().put(k, "19199999999","2");

        //獲取map
        Map m1 = redisTemplate.opsForHash().entries(k);
        Object o = redisTemplate.opsForHash().get(k, hashKey);
        log.info("get key:{}", o);
        log.info("map:{}", m1);

 

log打印的結果:

2019-12-13 15:45:36.836 INFO 4156 --- [ main] : get key:null
2019-12-13 15:45:36.836 INFO 4156 --- [ main] : map:{13838121333=1, 13838121556=2, 19199999999=2}

如果這里使用了redisTemplate.opsForHash().putAll(k, phoneMap); ,則get key打印的結果就是2。這里打印的map是包含之前測試的值。

 

示例測試操作2:

    @Test
    public void hashTest(){
        String k = "phoneMap";
        String hashKey = "19199999999";
        HashOperations<String, String, String> hash = redisTemplate.opsForHash();
        hash.increment(k,hashKey,1);
        log.info("19199999999:{}", hash.get(k,hashKey));

        Set set = hash.keys(k);
        log.info("phoneMap:{}", set);

        Long sizeLong = hash.size(k);
        log.info("sizeLong:{}",sizeLong);


        Cursor<Map.Entry<String, String>> cursor = hash.scan(k,ScanOptions.scanOptions().count(1000).build());
        while (cursor.hasNext()){
            Map.Entry<String, String> entry = cursor.next();
            log.info("entry:{}:{}", entry.getKey(), entry.getValue());
        }
        try {
            if (!cursor.isClosed()){
                cursor.close();
            }
        } catch (IOException e) {
            log.error("關閉cursor異常");
            e.printStackTrace();
        }
    }

打印結果:

2019-12-13 16:59:35.573  INFO 1540 --- [           main] : 19199999999:6
2019-12-13 16:59:35.577  INFO 1540 --- [           main] : phoneMap:[13838121333, 13838121556, 19199999999, 13838383839, 13838383838]
2019-12-13 16:59:35.578  INFO 1540 --- [           main] : sizeLong:5
2019-12-13 16:59:35.587  INFO 1540 --- [           main] : entry:13838121373:1
2019-12-13 16:59:35.587  INFO 1540 --- [           main] : entry:13838121556:2
2019-12-13 16:59:35.587  INFO 1540 --- [           main] : entry:19199999999:6
2019-12-13 16:59:35.587  INFO 1540 --- [           main] : entry:13838383839:1
2019-12-13 16:59:35.587  INFO 1540 --- [           main] : entry:13838383838:2

 

# 使用文件形式展示:

 

 

 

private final String REDIS_PHONE_CONUM_PREFIX_KEY = "phoneSms:Check";


/**
     * 添加手機號發送次數
     * @param phone
     * @return
     */
    public void setPhoneSmsCountInc(String phone){
        HashOperations hash = redisTemplate.opsForHash();
        if (!redisTemplate.hasKey(REDIS_PHONE_CONUM_PREFIX_KEY)){
            //設置過期key時間
            redisTemplate.expire(REDIS_PHONE_CONUM_PREFIX_KEY, 24 * 60 * 60, TimeUnit.SECONDS);
        }
        hash.increment(REDIS_PHONE_CONUM_PREFIX_KEY, phone,1);
    }

  

 

 

這是HashOperations的源碼:

/*
 * Copyright 2011-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.redis.core;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.lang.Nullable;

/**
 * Redis map specific operations working on a hash.
 *
 * @author Costin Leau
 * @author Christoph Strobl
 * @author Ninad Divadkar
 */
public interface HashOperations<H, HK, HV> {

    /**
     * Delete given hash {@code hashKeys}.
     *
     * @param key must not be {@literal null}.
     * @param hashKeys must not be {@literal null}.
     * @return {@literal null} when used in pipeline / transaction.
     */
    Long delete(H key, Object... hashKeys);

    /**
     * Determine if given hash {@code hashKey} exists.
     *
     * @param key must not be {@literal null}.
     * @param hashKey must not be {@literal null}.
     * @return {@literal null} when used in pipeline / transaction.
     */
    Boolean hasKey(H key, Object hashKey);

    /**
     * Get value for given {@code hashKey} from hash at {@code key}.
     *
     * @param key must not be {@literal null}.
     * @param hashKey must not be {@literal null}.
     * @return {@literal null} when key or hashKey does not exist or used in pipeline / transaction.
     */
    @Nullable
    HV get(H key, Object hashKey);

    /**
     * Get values for given {@code hashKeys} from hash at {@code key}.
     *
     * @param key must not be {@literal null}.
     * @param hashKeys must not be {@literal null}.
     * @return {@literal null} when used in pipeline / transaction.
     */
    List<HV> multiGet(H key, Collection<HK> hashKeys);

    /**
     * Increment {@code value} of a hash {@code hashKey} by the given {@code delta}.
     *
     * @param key must not be {@literal null}.
     * @param hashKey must not be {@literal null}.
     * @param delta
     * @return {@literal null} when used in pipeline / transaction.
     */
    Long increment(H key, HK hashKey, long delta);

    /**
     * Increment {@code value} of a hash {@code hashKey} by the given {@code delta}.
     *
     * @param key must not be {@literal null}.
     * @param hashKey must not be {@literal null}.
     * @param delta
     * @return {@literal null} when used in pipeline / transaction.
     */
    Double increment(H key, HK hashKey, double delta);

    /**
     * Get key set (fields) of hash at {@code key}.
     *
     * @param key must not be {@literal null}.
     * @return {@literal null} when used in pipeline / transaction.
     */
    Set<HK> keys(H key);

    /**
     * Returns the length of the value associated with {@code hashKey}. If either the {@code key} or the {@code hashKey}
     * do not exist, {@code 0} is returned.
     *
     * @param key must not be {@literal null}.
     * @param hashKey must not be {@literal null}.
     * @return {@literal null} when used in pipeline / transaction.
     * @since 2.1
     */
    @Nullable
    Long lengthOfValue(H key, HK hashKey);

    /**
     * Get size of hash at {@code key}.
     *
     * @param key must not be {@literal null}.
     * @return {@literal null} when used in pipeline / transaction.
     */
    Long size(H key);

    /**
     * Set multiple hash fields to multiple values using data provided in {@code m}.
     *
     * @param key must not be {@literal null}.
     * @param m must not be {@literal null}.
     */
    void putAll(H key, Map<? extends HK, ? extends HV> m);

    /**
     * Set the {@code value} of a hash {@code hashKey}.
     *
     * @param key must not be {@literal null}.
     * @param hashKey must not be {@literal null}.
     * @param value
     */
    void put(H key, HK hashKey, HV value);

    /**
     * Set the {@code value} of a hash {@code hashKey} only if {@code hashKey} does not exist.
     *
     * @param key must not be {@literal null}.
     * @param hashKey must not be {@literal null}.
     * @param value
     * @return {@literal null} when used in pipeline / transaction.
     */
    Boolean putIfAbsent(H key, HK hashKey, HV value);

    /**
     * Get entry set (values) of hash at {@code key}.
     *
     * @param key must not be {@literal null}.
     * @return {@literal null} when used in pipeline / transaction.
     */
    List<HV> values(H key);

    /**
     * Get entire hash stored at {@code key}.
     *
     * @param key must not be {@literal null}.
     * @return {@literal null} when used in pipeline / transaction.
     */
    Map<HK, HV> entries(H key);

    /**
     * Use a {@link Cursor} to iterate over entries in hash at {@code key}. <br />
     * <strong>Important:</strong> Call {@link Cursor#close()} when done to avoid resource leak.
     *
     * @param key must not be {@literal null}.
     * @param options
     * @return {@literal null} when used in pipeline / transaction.
     * @since 1.4
     */
    Cursor<Map.Entry<HK, HV>> scan(H key, ScanOptions options);

    /**
     * @return never {@literal null}.
     */
    RedisOperations<H, ?> getOperations();
}
View Code


免責聲明!

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



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