最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java對(duì)象以Hash結(jié)構(gòu)存入Redis詳解

 更新時(shí)間:2023年08月29日 08:51:19   作者:Abstracted  
這篇文章主要介紹了Java對(duì)象以Hash結(jié)構(gòu)存入Redis詳解,和Java中的對(duì)象非常相似,卻不能按照J(rèn)ava對(duì)象的結(jié)構(gòu)直接存儲(chǔ)進(jìn)Redis的hash中,因?yàn)镴ava對(duì)象中的field是可以嵌套的,而Redis的Hash結(jié)構(gòu)不支持嵌套結(jié)構(gòu),需要的朋友可以參考下

Java對(duì)象以Hash結(jié)構(gòu)存入Redis

Redis中Hash存儲(chǔ)結(jié)構(gòu):

Key:{
	filed: value,
	filed: value,
	filed: value,
	....
}

和Java中的對(duì)象非常相似,卻不能按照J(rèn)ava對(duì)象的結(jié)構(gòu)直接存儲(chǔ)進(jìn)Redis的hash中。因?yàn)镴ava對(duì)象中的field是可以嵌套的,而Redis的Hash結(jié)構(gòu)不支持嵌套結(jié)構(gòu)。(不允許套娃~)。

有的同學(xué)要問了,那我就是頭鐵,就要把帶嵌套屬性的對(duì)象存儲(chǔ)redis的hash中,應(yīng)該怎么辦?

Spring對(duì)所有的RedisClient進(jìn)行了封裝,提供了一個(gè)RedisTemplate。那我們看看RedisTemplate中對(duì)hash結(jié)構(gòu)的存儲(chǔ)都接受什么參數(shù)?

在這里插入圖片描述

從圖中可以看出:

  • 一次存一個(gè)KV
  • 一次性將Map中的所有KV都存入
  • 如果不存在就存入

一次只存一個(gè)KV就不用說了。重點(diǎn)是第二個(gè)putAll方法。既然是Map,那我們不就是可以將帶有嵌套屬性的對(duì)象轉(zhuǎn)成Map就可以存進(jìn)Redis了嗎?

但經(jīng)過實(shí)踐最終拋出了異常。正如上面已經(jīng)說過的,Redis的Hash結(jié)構(gòu)不允許套娃。而不帶有嵌套屬性的對(duì)象轉(zhuǎn)成Map后可以正常存入。

對(duì)象轉(zhuǎn)Map可以使用commons的BeanUtils中的toMap方法。

難道真的就沒有解決辦法了嗎?其實(shí)Spring已經(jīng)為我們提供了嵌套屬性轉(zhuǎn)Map的3中實(shí)現(xiàn)方案,也就是 HashMapper 接口

在這里插入圖片描述

  • BeanUtilsHashMapper:內(nèi)部依賴commons的BeanUtils將對(duì)象轉(zhuǎn)Map,但是官方注釋中也說明了這個(gè)實(shí)現(xiàn)類不支持嵌套屬性。
  • ObjectHashMapper:內(nèi)部使用的是RedisMappingConverter將給定的Java對(duì)象提供一個(gè)平面的映射,即支持嵌套屬性。
  • Jackson2HashMapper:內(nèi)部使用的是Jackon的ObjectMapper將對(duì)象轉(zhuǎn)換成扁平的Map
  • DecoratingStringHashMapper: 沒有什么特殊的,toHash方法實(shí)現(xiàn)了裝飾器(增強(qiáng))設(shè)計(jì)模式,對(duì)delegate.toHash的結(jié)果Map中的KV都進(jìn)行String.valueOf()操作。

可以看出 ObjectHashMapper 和 Jackson2HashMapper 的效果相同,用那個(gè)都可以。

注意:Jackson2HashMapper在為對(duì)象生成Map時(shí),內(nèi)部對(duì)ObjectMapper配置了對(duì)Date類型的序列化規(guī)則,會(huì)將其換成時(shí)間戳Long類型。 在執(zhí)行putAll時(shí),內(nèi)部會(huì)報(bào)ClassCastException Long cast to String,Long無法直接轉(zhuǎn)換為String。此時(shí)可以使用DecoratingStringHashMapper對(duì)Jackson2HashMapper進(jìn)行增強(qiáng)。

下面是一部分的示例代碼和截圖

@Autowired
    private RedisTemplate redisTemplate;
    /**
     * 測(cè)試Redis存Hash結(jié)構(gòu)數(shù)據(jù)
     */
    @Test
    void testSaveRedisHash() throws JsonProcessingException {
        User user = new User();user.setUserId(111);user.setPassword("psw");user.setName("張三");user.setCreateTime(new Date());
        ObjectMapper objectMapper = new ObjectMapper();
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        redisTemplate.setHashValueSerializer(RedisSerializer.string());
        // key, filed, value
        redisTemplate.opsForHash().put("testHash", "hashKey", "hashValue");
        // 直接寫JSON,并沒有什么卵用
        redisTemplate.opsForHash().put("testHash", "user", objectMapper.writeValueAsString(user));
        TestRedisHashObject testObj = new TestRedisHashObject(1, "測(cè)試時(shí)", new Date(), user);
        // 依賴第三方commons.beanUtils包
        redisTemplate.opsForHash().putAll("BeanUtilsHashMapper實(shí)現(xiàn)對(duì)象轉(zhuǎn)hash",new BeanUtilsHashMapper<>(TestRedisHashObject.class).toHash(testObj));
        // flatmap為true,才開啟json屬性path扁平化。
        // jackson2HashMapper中默認(rèn)的ObjectMapper對(duì)時(shí)間序列化成了long,而putAll方法中對(duì)long無法直接強(qiáng)轉(zhuǎn)成string。會(huì)發(fā)生ClassCastException
        // decoratingStringHashMapper:將map中的所有kv都使用StringValueOf進(jìn)行了增強(qiáng)
        redisTemplate.opsForHash().putAll("Jackson2HashMapper實(shí)現(xiàn)對(duì)象轉(zhuǎn)hash",new DecoratingStringHashMapper<>(new Jackson2HashMapper(true)).toHash(testObj));
        // ObjectHashMapper返回的Map的泛型是Map<byte[], byte[]> 需要自己手動(dòng)轉(zhuǎn)換。不推薦使用
        // decoratingStringHashMapper:String.valueOf方法無法對(duì)byte[]進(jìn)行轉(zhuǎn)成字符串
        // redisTemplate.opsForHash().putAll("ObjectHashMapper實(shí)現(xiàn)對(duì)象轉(zhuǎn)hash",new ObjectHashMapper().toHash(testObj));
    }
    /**
     * 測(cè)試Redis取Hash結(jié)構(gòu)數(shù)據(jù)
     */
    @Test
    void testGetRedisHash(){
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        redisTemplate.setHashValueSerializer(RedisSerializer.string());
        String key = "Jackson2HashMapper實(shí)現(xiàn)對(duì)象轉(zhuǎn)hash";
        Object o = new Jackson2HashMapper(true).fromHash(redisTemplate.opsForHash().entries(key));
        TestRedisHashObject testObj = (TestRedisHashObject) o;
        System.out.println(testObj);
        Long newCount = redisTemplate.opsForHash().increment(key, "count", 10L);
        System.out.println("newCount = " + newCount);
        o = new Jackson2HashMapper(true).fromHash(redisTemplate.opsForHash().entries(key));
        testObj = (TestRedisHashObject) o;
        System.out.println(testObj);
		Object c = redisTemplate.opsForHash().get(key, "count");
        Long count = (Long) c;
        System.out.println("getCount = " + count);
    }

在這里插入圖片描述

在這里插入圖片描述

到此這篇關(guān)于Java對(duì)象以Hash結(jié)構(gòu)存入Redis詳解的文章就介紹到這了,更多相關(guān)Java對(duì)象存入Redis內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 更改Maven軟件源為阿里云源的方法詳解

    更改Maven軟件源為阿里云源的方法詳解

    這篇文章主要介紹了更改Maven軟件源為阿里云源的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • swagger整合gateway實(shí)現(xiàn)文檔集中化過程

    swagger整合gateway實(shí)現(xiàn)文檔集中化過程

    本文介紹了如何將Swagger與Spring?Cloud?Gateway整合,實(shí)現(xiàn)API文檔的集中化管理,通過Spring?Boot的自動(dòng)裝配,配置了網(wǎng)關(guān)Swagger資源提供程序,實(shí)現(xiàn)了通過gateway路由的方式聚合Swagger文檔,整個(gè)過程包括了文件夾結(jié)構(gòu)、自動(dòng)裝配文件內(nèi)容等詳細(xì)步驟
    2026-02-02
  • java定義通用返回結(jié)果類ResultVO使用示例詳解

    java定義通用返回結(jié)果類ResultVO使用示例詳解

    這篇文章主要為大家介紹了java定義通用返回結(jié)果類ResultVO使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • SpringBoot整合Redis實(shí)現(xiàn)登錄失敗鎖定功能(實(shí)例詳解)

    SpringBoot整合Redis實(shí)現(xiàn)登錄失敗鎖定功能(實(shí)例詳解)

    本文我們已經(jīng)探討如何利用Redis來實(shí)現(xiàn)鎖定賬戶的安全措施,以及通過SpringBoot整合Redis實(shí)現(xiàn)了這一功能,感興趣的朋友跟隨小編一起學(xué)習(xí)下吧
    2024-02-02
  • Java中的Caffeine加載與驅(qū)逐策略詳解

    Java中的Caffeine加載與驅(qū)逐策略詳解

    這篇文章主要介紹了Java中的Caffeine加載與驅(qū)逐策略詳解,Caffeine是基于Java 8的高性能緩存庫(kù),可提供接近最佳的命中率,Caffeine與ConcurrentMap相應(yīng),但是不完全相同,本文主要介紹Caffeine,需要的朋友可以參考下
    2023-10-10
  • Java求素?cái)?shù)和最大公約數(shù)的簡(jiǎn)單代碼示例

    Java求素?cái)?shù)和最大公約數(shù)的簡(jiǎn)單代碼示例

    這篇文章主要介紹了Java求素?cái)?shù)和最大公約數(shù)的簡(jiǎn)單代碼示例,其中作者創(chuàng)建的Fraction類可以用來進(jìn)行各種分?jǐn)?shù)運(yùn)算,需要的朋友可以參考下
    2015-09-09
  • 詳解@ConditionalOnMissingBean注解的作用

    詳解@ConditionalOnMissingBean注解的作用

    這篇文章主要介紹了詳解@ConditionalOnMissingBean注解的作用,@ConditionalOnMissingBean,它是修飾bean的一個(gè)注解,主要實(shí)現(xiàn)的是,當(dāng)你的bean被注冊(cè)之后,如果而注冊(cè)相同類型的bean,就不會(huì)成功,它會(huì)保證你的bean只有一個(gè),需要的朋友可以參考下
    2023-10-10
  • Spring Boot配置接口WebMvcConfigurer的實(shí)現(xiàn)

    Spring Boot配置接口WebMvcConfigurer的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot配置接口WebMvcConfigurer的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Java編程實(shí)現(xiàn)從給定范圍內(nèi)隨機(jī)N個(gè)不重復(fù)數(shù)生成隨機(jī)數(shù)的方法小結(jié)

    Java編程實(shí)現(xiàn)從給定范圍內(nèi)隨機(jī)N個(gè)不重復(fù)數(shù)生成隨機(jī)數(shù)的方法小結(jié)

    這篇文章主要介紹了Java編程實(shí)現(xiàn)從給定范圍內(nèi)隨機(jī)N個(gè)不重復(fù)數(shù)生成隨機(jī)數(shù)的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了java根據(jù)指定范圍生成不重復(fù)隨機(jī)數(shù)的相關(guān)操作技巧,需要的朋友可以參考下
    2017-04-04
  • 淺談一下Servlet的定義以及運(yùn)行原理

    淺談一下Servlet的定義以及運(yùn)行原理

    相信有很多剛?cè)胄械呐笥褧?huì)疑惑Servlet到底是個(gè)什么意思,那么這篇文章就來淺談一下到底什么是Servlet,以及Servlet的原理與如何寫一個(gè)Servlet,,需要的朋友可以參考下
    2023-03-03

最新評(píng)論

梁山县| 赣榆县| 巴彦淖尔市| 嘉义市| 双柏县| 孟津县| 裕民县| 吉水县| 嘉峪关市| 南安市| 化隆| 寻乌县| 葵青区| 永川市| 舟山市| 东莞市| 什邡市| 山西省| 宜兴市| 苏尼特右旗| 雷波县| 昌乐县| 台前县| 莱西市| 泗洪县| 通河县| 山东| 永福县| 广丰县| 集贤县| 格尔木市| 历史| 碌曲县| 德州市| 蓝田县| 信宜市| 江阴市| 田阳县| 南京市| 新化县| 横山县|