日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis-04Redis数据结构--哈希hash

發布時間:2025/3/21 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis-04Redis数据结构--哈希hash 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 哈希概述
  • 客戶端操作hash
  • Redis hash 結構命令
  • Spring操作reids的hash
    • Step1 修改defaultSerializer
    • Step2 操作hash
  • 注意
  • 代碼

哈希概述

Redis 中哈希結構就如同 Java 的 map 一樣 , 一個對象里面有許多鍵值對,它是特別適合存儲對象的.

如果內存足夠大 ,那么一個 Redis 的 hash 結構可以存儲2的32次方-1個鍵值對 ( 40多億)。

在 Redis 中, hash 是一個 String 類型的 field 和 value 的映射表,因此我們存儲的數據實際在 Redis 內存中都是一個個字符串而己。

假設artisan有 3 個字段 : 編號( id)、名稱 (name )、性別( sex),這樣就可以使用一個 hash 結構保存它。

在 Redis 中它就是一個這樣的結構,其中 artisan代表的是這個 hash 結構在 Redis 內存的 key,通過它就可以找到這個 hash 結構,而 hash 結構由一系列的 field 和 value 組成


客戶端操作hash

127.0.0.1:6379> HMSET artisan id 123 name littleArtisan sex female OK 127.0.0.1:6379> HGETALL artisan 1) "id" 2) "123" 3) "name" 4) "littleArtisan" 5) "sex" 6) "female" 127.0.0.1:6379>

Redis hash 結構命令

官網:https://redis.io/commands#hash

命令說明備注
hdel key field 1 [ field2 …]刪除 hash 結構中的某個(些)字段可以進行多個字段的刪除
hexists key field判斷 hash 結構中是否存在 field 字段存在返回 1 ,否則返回0
hgetall key獲取所有 hash 結構中的鍵值返回鍵和值
hincrby key field increment指定給 hash 結構中的某一字段加上一個整數要求該字段也是整數字符串
hincrbyfloat key field increment指定給 hash 結構中的某一字段加上一個浮點數要求該字段是數字型字符串
hkeys key返回 hash 中所有的鍵
hlen key返問 hash 中鍵值對的數量
hmget key field1 [field2…]返回 hash 中指定的鍵的值,可以是多個依次返回值
hmset key field1 value1 [field2 value2…]hash 結構設置多個鍵值對
hset key filed value在 hash 結構中設置鍵值對單個設值
hsetnx key field value當 hash 結構中不存在對應的鍵,才設置值
hvals key獲取 hash 結構中所有的值

在 Redis 中的哈希結構和字符串有著比較明顯的不同。

  • 首先,命令都是以 h 開頭,代表操作的是 hash 結構

  • 其次,大多數命令多了一個層級 field,這是hash 結構的一個內部鍵,也就是說Redis 需要通過 key 索引到對應的 hash 結構,再通過 field來確定使用 hash 結構的哪個鍵值對

注意事項:

  • 哈希結構的大小,如果哈希結構是個很大的鍵值對,那么使用它要十分注意。 尤其是關于 hkeys 、 hgetall 、 hvals 等返回所有哈希結構數據的命令,會造成大量數據的讀取。這需要考慮性能和讀取數據大小對 JVM 內存的影響 。
  • 對于數字的操作命令 hincrby 而言,要求存儲的也是整數型的字符串
  • 對于hincrbyfloat 而言,則要求使用浮點數或者整數,否則命令會失敗。
127.0.0.1:6379> flushdb OK 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> HMSET obj k1 value1 k2 value2 k3 value3 OK 127.0.0.1:6379> HSET obj k4 6 (integer) 1 127.0.0.1:6379> HEXISTS obj k2 (integer) 1 127.0.0.1:6379> HGETALL obj 1) "k1" 2) "value1" 3) "k2" 4) "value2" 5) "k3" 6) "value3" 7) "k4" 8) "6" 127.0.0.1:6379> HINCRBY obj k4 8 (integer) 14 127.0.0.1:6379> HINCRBYFLOAT obj k4 6.2 "20.2" 127.0.0.1:6379> HKEYS obj 1) "k1" 2) "k2" 3) "k3" 4) "k4" 127.0.0.1:6379> HMGET obj k1 k2 k4 1) "value1" 2) "value2" 3) "20.2" 127.0.0.1:6379> HLEN obj (integer) 4 127.0.0.1:6379> HSETNX obj k2 test (integer) 0 127.0.0.1:6379> HSETNX obj k5 test (integer) 1 127.0.0.1:6379> HGETALL obj1) "k1"2) "value1"3) "k2"4) "value2"5) "k3"6) "value3"7) "k4"8) "20.2"9) "k5" 10) "test" 127.0.0.1:6379> HVALS obj 1) "value1" 2) "value2" 3) "value3" 4) "20.2" 5) "test" 127.0.0.1:6379> HDEL obj k5 (integer) 1 127.0.0.1:6379> HGETALL obj 1) "k1" 2) "value1" 3) "k2" 4) "value2" 5) "k3" 6) "value3" 7) "k4" 8) "20.2" 127.0.0.1:6379> HGET obj k4 "20.2" 127.0.0.1:6379>

Spring操作reids的hash

Step1 修改defaultSerializer

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="classpath:redis/redis.properties" /><!--2,注意新版本2.3以后,JedisPoolConfig的property name,不是maxActive而是maxTotal,而且沒有maxWait屬性,建議看一下Jedis源碼或百度。 --><!-- redis連接池配置 --><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><!--最大空閑數 --><property name="maxIdle" value="${redis.maxIdle}" /><!--連接池的最大數據庫連接數 --><property name="maxTotal" value="${redis.maxTotal}" /><!--最大建立連接等待時間 --><property name="maxWaitMillis" value="${redis.maxWaitMillis}" /><!--逐出連接的最小空閑時間 默認1800000毫秒(30分鐘) --><property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" /><!--每次逐出檢查時 逐出的最大數目 如果為負數就是 : 1/abs(n), 默認3 --><property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" /><!--逐出掃描的時間間隔(毫秒) 如果為負數,則不運行逐出線程, 默認-1 --><property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" /><property name="testOnBorrow" value="true"></property><property name="testOnReturn" value="true"></property><property name="testWhileIdle" value="true"></property></bean><!--redis連接工廠 --><bean id="jedisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"destroy-method="destroy"><property name="poolConfig" ref="jedisPoolConfig"></property><!--IP地址 --><property name="hostName" value="${redis.host.ip}"></property><!--端口號 --><property name="port" value="${redis.port}"></property><!--如果Redis設置有密碼 --><property name="password" value="${redis.password}" /> <!--客戶端超時時間單位是毫秒 --><property name="timeout" value="${redis.timeout}"></property><property name="usePool" value="true" /><!--<property name="database" value="0" /> --></bean><!-- 鍵值序列化器設置為String 類型 --><bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/><!-- redis template definition --><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"p:connection-factory-ref="jedisConnectionFactory"p:keySerializer-ref="stringRedisSerializer"p:defaultSerializer-ref="stringRedisSerializer"p:valueSerializer-ref="stringRedisSerializer"></bean></beans>

在 Redis 中, hash 是一個 String 類型的 field 和 value 的映射表。 Spring 對 Redis 進行了封裝,所以有必要對 RedisTemplate 的配置項進行修改。修改defaultSerializer-ref

如果不指定的話就是

否則拋出如下異常

Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.EOFException

Step2 操作hash

package com.artisan.redis.baseStructure.hash;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.data.redis.core.RedisTemplate;public class SpringRedisHashDemo {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring/spring-redis-hash.xml");RedisTemplate redisTemplate = (RedisTemplate) ctx.getBean("redisTemplate");// 127.0.0.1:6379> HMSET obj k1 value1 k2 value2 k3 value3// OKString key = "obj";Map<String, String> map = new HashMap<String, String>();map.put("k1", "value1");map.put("k2", "value2");map.put("k3", "value3");redisTemplate.opsForHash().putAll(key, map);// 127.0.0.1:6379> HSET obj k4 6// (integer) 1redisTemplate.opsForHash().put(key, "k4", String.valueOf(6));// 127.0.0.1:6379> HEXISTS obj k2// (integer) 1boolean exist = redisTemplate.opsForHash().hasKey(key, "k2");System.out.println(key + " 這個鍵中是否存在 k2這個field:" + exist);// 127.0.0.1:6379> HGETALL obj// 1) "k1"// 2) "value1"// 3) "k2"// 4) "value2"// 5) "k3"// 6) "value3"// 7) "k4"// 8) "6"Map<String,String> map2 = redisTemplate.opsForHash().entries(key);if (map2 != null) {scanMap(map2);}// 127.0.0.1:6379> HINCRBY obj k4 8// (integer) 14System.out.println(redisTemplate.opsForHash().increment(key, "k4", 8));// 127.0.0.1:6379> HINCRBYFLOAT obj k4 6.2// "20.2"System.out.println(redisTemplate.opsForHash().increment(key, "k4", 6.2));// 127.0.0.1:6379> HKEYS obj// 1) "k1"// 2) "k2"// 3) "k3"// 4) "k4"Set<String> set = redisTemplate.opsForHash().keys(key);for (String str : set) {System.out.println(str);}// 127.0.0.1:6379> HMGET obj k1 k2 k4// 1) "value1"// 2) "value2"// 3) "20.2"List<String> list = new ArrayList<String>();list.add("k1");list.add("k2");list.add("k4");List<String> list2 = redisTemplate.opsForHash().multiGet(key, list);scanList(list2);// 127.0.0.1:6379> HLEN obj// (integer) 4System.out.println(redisTemplate.opsForHash().size(key));// 127.0.0.1:6379> HSETNX obj k2 test// (integer) 0System.out.println(redisTemplate.opsForHash().putIfAbsent(key, "k2", "test"));// 127.0.0.1:6379> HSETNX obj k5 test// (integer) 1System.out.println(redisTemplate.opsForHash().putIfAbsent(key, "k5", "test"));// 127.0.0.1:6379> HGETALL obj// 1) "k1"// 2) "value1"// 3) "k2"// 4) "value2"// 5) "k3"// 6) "value3"// 7) "k4"// 8) "20.2"// 9) "k5"// 10) "test"Map<String, String> map3 = redisTemplate.opsForHash().entries(key);if (map3 != null) {scanMap(map3);}// 127.0.0.1:6379> HVALS obj// 1) "value1"// 2) "value2"// 3) "value3"// 4) "20.2"// 5) "test"List<String> list3 = redisTemplate.opsForHash().values(key);scanList(list3);// 127.0.0.1:6379> HDEL obj k5// (integer) 1redisTemplate.opsForHash().delete(key, "k5");// 127.0.0.1:6379> HGETALL obj// 1) "k1"// 2) "value1"// 3) "k2"// 4) "value2"// 5) "k3"// 6) "value3"// 7) "k4"// 8) "20.2"Map<String, String> map4 = redisTemplate.opsForHash().entries(key);if (map4 != null) {scanMap(map4);}// 127.0.0.1:6379> HGET obj k4// "20.2"System.out.println(redisTemplate.opsForHash().get(key, "k4"));}private static void scanList(List<String> list2) {for (String string : list2) {System.out.println(string);}}private static void scanMap(Map<String, String> map4) {for (Map.Entry<String, String> entry : map4.entrySet()) {System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());}} }

輸出

INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@73a8dfcc: startup date [Thu Sep 20 19:13:10 CST 2018]; root of context hierarchy INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [spring/spring-redis-hash.xml] obj 這個鍵中是否存在 k2這個field:true Key = k2, Value = value2 Key = k3, Value = value3 Key = k4, Value = 6 Key = k1, Value = value1 14 20.2 k1 k2 k3 k4 value1 value2 20.2 4 false true Key = k2, Value = value2 Key = k5, Value = test Key = k3, Value = value3 Key = k1, Value = value1 Key = k4, Value = 20.2 value1 value2 value3 20.2 test Key = k3, Value = value3 Key = k2, Value = value2 Key = k4, Value = 20.2 Key = k1, Value = value1 20.2
  • hmset 命令,在 Java 的 API 中,是使用 map 保存多個鍵值對。
  • hgetall 命令會返回所有的鍵值對,并保存到一個 map 對象中,如果 hash 結構很大,那么要考慮它對 JVM 的內存影響。
  • hincrby 和 hincrbyFloat 命令都采用 increment 方法, Spring 會識別它具體使用何種方法。
  • redisTemplate.opsForHash().values(key)方法相當于 hvals 命令,它會返回所有的值,并保存到一個 List 對象中;
  • redisTemplate.opsForHash().keys(key)方法相當于 hkeys命令,它會獲取所有的鍵,保存到一個 Set 對象中 。
  • 在 Spring 中使用 redisTemplate.opsForHash().putAll(key, map )方法相當于執行了hmset 命令,使用了 map ,由于配置了默認的序列化器為字符串,所以它也只會用字符串進行轉化,這樣才能執行對應的數值加法,如果使用其他序列化器,則后面的命令可能會拋出異常。
  • 在使用大的 hash 結構時,需要考慮返回數據的大小,以避免返回太多的數據,引發JVM內存溢出或者 Redis 的性能問題。

注意

使用 Spring 提供的 RedisTemplate 去展示多個命令可以學習到如何使用 RedisTemplate 操作 Redis 。 實際工作中并不是那么用的,因為每一 個操作會嘗試從連接池里獲取 一 個新的 Redis 連接,多個命令應該使用SessionCallback 接口進行操作 。


代碼

代碼托管到了 https://github.com/yangshangwei/redis_learn

總結

以上是生活随笔為你收集整理的Redis-04Redis数据结构--哈希hash的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产资源站 | 夜夜爱爱 | 亚洲美女在线观看 | 黄色三级视频在线观看 | 国产老头老太作爱视频 | 日韩a级在线观看 | 成人网站免费观看 | 成人天堂av | 色男人天堂av | 神马福利视频 | 午夜激情黄色 | 狠狠干男人的天堂 | 中文字幕一区二区久久人妻 | 久操这里只有精品 | 麻豆极品 | 99精品久久99久久久久 | 一本色道久久综合亚洲二区三区 | 日本黄色免费网站 | 欧美一区精品 | 日韩精品一区二区三区四区 | 亚洲成人动漫在线观看 | 黄色av中文字幕 | 狠狠插视频 | 粉嫩av一区二区夜夜嗨 | 91亚洲精品久久久久久久久久久久 | 国产精品欧美激情在线播放 | av大全在线观看 | 日本韩国在线观看 | 婷婷丁香综合网 | 美女久久久久久久久久 | 国产无套内射普通话对白 | 免费一级片网站 | 国产精品12p | 中文字幕伦理 | 欧美国产大片 | 国产精品色婷婷99久久精品 | av免费看在线 | 假日游船 | 一区二区三区久久久久 | 熟女高潮一区二区三区 | 免费精品视频在线 | 高潮毛片无遮挡免费看 | 欧美精品午夜 | 极品少妇xxxx精品少妇 | 天天爽夜夜爽一区二区三区 | 中文字幕在线观看免费视频 | 爆操老女人 | 伊人免费在线观看 | 久久日韩| 精品国产三级片在线观看 | h片在线| 国产免费一区视频观看免费 | 免费古装一级淫片潘金莲 | 五月天婷婷视频 | 久草视频免费 | 欧美日韩色 | 男女午夜激情视频 | 国产第十页 | 精品人妻二区中文字幕 | 青青草超碰在线 | 成人精品国产 | 四虎影库在线播放 | 久久精品国产成人av | 琪琪电影午夜理论片八戒八戒 | 中文字幕一区二区三区精华液 | 久久国产夫妻 | 亚洲av成人片无码 | 激情区| 日本三级视频在线观看 | 女性裸体下面张开 | 91精品国产色综合久久不8 | 日本亚洲最大的色成网站www | 熟妇人妻av无码一区二区三区 | 欧美又粗又长又爽做受 | 天天爱天天草 | 日本网站在线免费观看 | 国产精品久久久久久在线观看 | 国产精品久久一区 | 在线播放你懂的 | 男女福利视频 | 国产亚洲精品久久久久婷婷瑜伽 | 欧美激情一区二区在线 | 欧美片网站yy | 免费毛片网站在线观看 | 国产无遮挡免费视频 | 欧美日一区二区三区 | 国产日韩欧美电影 | 男人天堂免费视频 | 每日在线更新av | 成人听书哪个软件好 | 美女av网| 国产又粗又黄又爽又硬的视频 | 日本免费不卡 | 男人看的网站 | 中文字幕在线播放一区 | 88av在线播放 | 日韩午夜片 | 亚洲一区二区三区影视 | 精品国产乱码久久久久久蜜臀 |