Redis5:Redis的Java客戶端——Jedis與SpringDataRedis詳解

目錄

1、Jedis客戶端

1.1使用過程

2、SpringDataRedis

2.1 SpingDataRedis介紹

2.2SpringDataRedis快速入門

2.3RedisTemplate的RedisSerializer

2.3.1RedisTemplate中JDK序列化局限性

2.3.2方式一:改變RedisTemplate的序列化方式

2.3.3RedisTemplate存儲一個對象

2.3.4 方式二:StringRedisTemplate


1、Jedis客戶端

1.1使用過程

1、新建一個maven項目

2、引入依賴

<!--jedis-->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</version>
</dependency><!--單元測試-->
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>RELEASE</version><scope>test</scope>
</dependency>

3、建立連接

@BeforeEach
void setUp(){//1、建立連接jedis = new Jedis("120.53.240.101",6379);//2、設置密碼jedis.auth("123321");//3、選擇庫jedis.select(5);
}

注意!!Jedis本身是線程不安全的,并且頻繁的創建和銷毀連接會有性能損耗,因此推薦使用Jedis連接池代替Jedis的直連方式

package com.tang.util;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;public class JedisConnectionFactory {// Jedis連接池對象private static JedisPool jedisPool;static {//配置連接池JedisPoolConfig jedisPoolConfig  = new JedisPoolConfig();//  最大連接數jedisPoolConfig.setMaxTotal(8);// 最大空閑連接數,最多可創建的連接jedisPoolConfig.setMaxIdle(8);// 最小空閑連接數,最少可創建的連接數,長時間沒鏈接時就銷毀至0,當然也可以預備一些連接jedisPoolConfig.setMinIdle(0);//默認值是-1,表示沒有限制// 設置最長等待時間(ms),連接池里沒有連接時就等待,超過這個時間就拋異常jedisPoolConfig.setMaxWaitMillis(1000);//創建連接池對象,1000是連接超時時間jedisPool = new JedisPool(jedisPoolConfig,"120.53.240.101", 6379, 1000, "123321");}// 獲取Jedis實例public static Jedis getJedis() {return jedisPool.getResource();}}

在測試類中,連接直接從工具類里拿

@BeforeEach
void setUp(){//1、建立連接jedis = JedisConnectionFactory.getJedis();//2、選擇庫jedis.select(6);
}

4、測試string

set類型

@Test
void testString(){ //存入數據String result = jedis.set("name","tang");System.out.println("result="+result);//獲取數據String name = jedis.get("name");System.out.println("name="+name);
}

Hash類型

@Test
void testHash(){jedis.hset("user","name","tang");jedis.hset("user","age","22");Map<String, String> user = jedis.hgetAll("user");System.out.println(user);
}

5、釋放資源

@AfterEach
void tearDown(){//健壯性判斷,關閉鏈接if(jedis != null){jedis.close();}
}

6、結果返回

string

hash

2、SpringDataRedis

2.1 SpingDataRedis介紹

SpringData是Spring中數據操作的模塊,包含對各種數據庫的集成,其中對Redis的集成模塊就叫做SpringDataRedis,

官網Spring Data Redis

  • 提供了對不同Redis客戶端的整合(Lettuce和jedis)

  • 提供了RedisTemplate統一API來操作Redis

  • 支持Redis的發布訂閱模型

  • 支持Redis哨兵和Redis集群

  • 支持基于Lettuce的響應式編程

  • 支持基于JDK、JSON、字符串、Spring對象的數據序列化及反序列化

2.2SpringDataRedis快速入門

????????SPringDataRedis中提供了RedisTemplate工具類,其中封裝了各種對Redis的操作。并且將不同數據類型的操作API封裝到了不同的類型中:

SpringBoot已經提供了對SpringDataRedis的支持,使用非常簡單:

新建項目,我們在這創建一個SpringBoot項目

可以提前勾選幾個依賴。(注意!!在我這,這個SpringBoot版本進去要改一下,不然會因為版本過高等問題出錯

1、導入依賴

<!--Redis依賴-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--連接池依賴-->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.11.1</version>
</dependency>

2、配置文件

spring:redis:host: 120.53.240.101port: 6379password: 123321lettuce:pool:max-active: 8  #最大連接max-idle: 8 #最大空閑連接min-idle: 0 #最小空閑連接max-wait: 100 #最大等待時間

3、注入RedisTemplate

@Autowired
private RedisTemplate redisTemplate;

4、編寫測試

在這里我們看到,set()并沒有強硬要求我們必須傳入字符串參數

@Test
void testString() {//寫入一條String類型數據redisTemplate.opsForValue().set("name","tang");//讀取一條String類型數據Object name = redisTemplate.opsForValue().get("name");System.out.println("name="+name);
}

2.3RedisTemplate的RedisSerializer

2.3.1RedisTemplate中JDK序列化局限性

當我們嘗試用SpringDataRdies修改某個鍵的值時,會發現如下情景:

我們先在數據庫中存入鍵name,并把他的value設為Jack

然后我們調用SpringDataRedis,將鍵name的value設置為tang

得到如下返回結果

回到我們的redis命令行去get name,

我們會發現name的值并未改變

獲取一下全部的keys,出現一串不知名的key。

我們來get一下這個key,返回的還是一串字符

為什么會這樣子?

????????我們看set方法我們發現他接受的并不是字符串,它可以接收任何類型的對象,然后轉換成redis可以處理的字節(JDK的序列化工具ObjectOutputStream)再寫入redis。

debug進入set方法,我們發現它最終進入到了JdkSerializer

最后調用ObjectOutputStream

這樣寫有什么問題?

  • 可讀性差

  • 內存占用較大

  • 容易出現bug:不是修改,因為key也被序列化

2.3.2方式一:改變RedisTemplate的序列化方式

crtl+H查看RedisSerializer的subTypes

JdkSerializationRedisSerializer我們已經發現它并不好用。

StringRedisSerializer是專門處理字符串的序列化工具getbytes:當key或者hashkey是字符串類型的時候可以使用。

GenericJackson2JsonRedisSerializer這是一個轉JSON字符串的序列化工具:適合于value使用

我們手寫一個工具類,自定義RedisTemplate的序列化方式

package com.tang.springdataredisdemo.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import sun.net.www.content.text.Generic;/*** 注冊一個配置類,實現自定義Redis序列化* @author tang* @date 2021-06-07 16:05* @desc*/
@Configuration
public class RedisConfig {@Bean// 自定義Redis序列化public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {//創建RedisTemplate對象RedisTemplate<String, Object> template = new RedisTemplate<>();//設置連接工廠template.setConnectionFactory(connectionFactory);//創建JSON的序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();//設置key序列化方式template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());//設置value序列化方式template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);//返回RedisTemplate對象return template;}
}

添加這個配置類后,我們對測試的部分進行一些修改,改為泛型格式

@Autowired
private RedisTemplate<String,Object> redisTemplate;

還需要添加一個依賴

<!--Jackson依賴-->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>

idea里結果返回如下:

現在去redis數據庫里看一下,沒問題了!

2.3.3RedisTemplate存儲一個對象

創建一個User類

package com.tang.springdataredisdemo.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private String name;private Integer age;
}

編寫測試案例

@Test
void testObject() {User user = new User("tang", 18);//寫入一條Object類型數據redisTemplate.opsForValue().set("user:100",user);//讀取一條Object類型數據(直接強轉)User user1 =(User) redisTemplate.opsForValue().get("user:100");System.out.println("user="+user1);
}

結果返回如下

在數據庫中,自動轉化為JSON風格的數據存儲起來

圖片上的JSON中還有一個“@class”,這個字段幫助將json格式反序列化為對應的對象(反射

但這會帶來額外的內存開銷

2.3.4 方式二:StringRedisTemplate

在2.3.3中我們發現使用GenericJackson2JsonRedisSerializer會產生額外的字段,消耗了很大一部分的內存空間。

為了節省內存空間,我們并不會使用JSON序列化器來處理value,而是統一使用String序列化器,要求只能存儲String類型的key和value。當需要存儲Java對象時,手動完成對象的序列化和反序列化

Spring默認提供了一個StringRedisTemplate類,他的key和value的序列化方式默認就是String方式。省去了我們自定義的時間。

在測試類注入

@Autowired
private StringRedisTemplate  stringRedisTemplate;

修改測試用例,在存入對象的部分多了一個手動序列化和反序列化的過程

@Test
void testString() {//寫入一條String類型數據stringRedisTemplate.opsForValue().set("name","tang");//讀取一條String類型數據Object name = stringRedisTemplate.opsForValue().get("name");System.out.println("name="+name);
}
@Test
void testHash(){stringRedisTemplate.opsForHash().put("user:200","name","tang");stringRedisTemplate.opsForHash().put("user:200","age","18");Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:200");System.out.println("entries="+entries);}
//序列化工具,使用fastjson也是可以的
private static final ObjectMapper objectMapper = new ObjectMapper();@Test
void testObject() throws JsonProcessingException {//創建對象User user = new User("tang", 18);//手動序列化String json = objectMapper.writeValueAsString(user);//寫入一條Object類型數據stringRedisTemplate.opsForValue().set("user:100",json);//讀取一條Object類型數據(直接強轉)String jsonUser =stringRedisTemplate.opsForValue().get("user:100");//手動反序列化objectMapper.readValue(jsonUser,User.class);System.out.println("user="+jsonUser);
}

結果顯示

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915430.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915430.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915430.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

零基礎 “入坑” Java--- 十三、再談類和接口

文章目錄一、Object類1.獲取對象信息2.對象比較&#xff1a;equals方法二、再談接口1.比較相關接口2.Cloneable接口和深拷貝三、內部類1.匿名內部類2.實例內部類3.靜態內部類4.局部內部類在之前的學習中&#xff0c;我們已經了解了有關類以及接口的知識&#xff0c;在本章節中&…

Spring Boot 一個注解搞定「加密 + 解密 + 簽名 + 驗簽」

Spring Boot 一個注解搞定「加密 解密 簽名 驗簽」本文基于 Spring Boot 3.x&#xff0c;通過一個自定義注解 AOP&#xff0c;一行注解即可給任何 Controller 方法加上 請求解密 → 驗簽 → 響應加密 → 加簽 的完整鏈路&#xff0c;并可直接拷貝到生產環境使用。一、最終效…

《計算機網絡》實驗報告二 IP協議分析

目 錄 1、實驗目的 2、實驗環境 3、實驗內容 3.1 tcpdump 基本用法 3.2 wireshark基本用法 3.3 利用tcpdump抓包&#xff0c;wireshark分析包 4、實驗結果與分析 4.1 tcpdump命令的基本用法 4.2 wireshark的基本用法 4.3 利用tcpdump抓包&#xff0c;wireshark分析包…

k8s學習記錄(三):Pod基礎-Node選擇

一、前言 在上一篇文章中我們學習了Pod的一些基本的知識&#xff0c;今天我們將繼續學習Pod。 二、K8S如何選擇節點來運行Pod 我們知道在一個K8S集群中&#xff0c;會有多個工作節點&#xff08;Worker Node&#xff09;&#xff0c;那么k8s會選擇那個node呢&#xff1f;接下…

3天功能開發→3小時:通義靈碼2.0+DEEPSEEK實測報告,單元測試生成準確率92%的秘密

活動鏈接&#xff1a;https://developer.aliyun.com/topic/lingma-aideveloper?spma2c6h.29979852.J_9593490300.2.49b8110eeymlF8 前言 隨著人工智能技術的迅猛發展&#xff0c;AI 賦能編程成為了必然趨勢。通義靈碼應運而生&#xff0c;它是阿里巴巴集團在人工智能與編程領…

【小沐學GIS】基于Rust繪制三維數字地球Earth(Rust、OpenGL、GIS)

&#x1f37a;三維數字地球GIS系列相關文章如下&#x1f37a;&#xff1a;1【小沐學GIS】基于C繪制三維數字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第一期2【小沐學GIS】基于C繪制三維數字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第二期3【小沐學GI…

ARM 學習筆記(三)

參考文獻&#xff1a;《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》《ARM Cortex-A (ARMv7-A) Series Programmer’s Guide》1、內存類型 ARMv7-A 處理器中&#xff0c;將 Memory 定義為幾種類型&#xff08;Memory Type&#xff09;&#xff1a; Strong…

Flask 框架(一):核心特性與基礎配置

目錄 一、為什么選擇 Flask&#xff1f; 二、Flask 核心概念與初始化 2.1 程序實例初始化 2.2 運行配置&#xff1a;app.run () 參數詳解 2.3 應用配置&#xff1a;三種參數設置方式 1. 字典直接配置&#xff08;簡單臨時場景&#xff09; 2. 配置文件導入&#xff08;生…

社交圈子系統開源社交源碼 / 小程序+H5+APP 多端互通的底層技術分析

伴隨社交產品向“圈子化”、“內容驅動”發展方向演進&#xff0c;打造一套支持小程序、H5、APP 互通的社交圈子系統&#xff0c;已經成為構建垂直社區的基礎架構能力要求。本文圍繞一套典型的多端社交興趣平臺&#xff08;即友貓社區平臺&#xff09;的設計實踐&#xff0c;對…

gitlab-runner配置問題記錄

引言 筆者曾通過2種方式部署過 gitlab-runner&#xff0c;在 gitlab 中使用這個 runner 拉起 ci job 的過程中或多或少遇到些問題&#xff0c;主要都是 job 中無法訪問宿主機的docker 等組件。本篇文檔主要記錄 gitlab-runner 安裝及相關配置。 二進制部署 gitlab-runner 部署 …

每日面試題10:令牌桶

令牌桶算法&#xff1a;優雅的流量控制藝術在現代分布式系統中&#xff0c;流量控制如同交通信號燈般重要——它既不能讓請求"堵死"系統&#xff0c;也不能放任流量"橫沖直撞"。令牌桶算法&#xff08;Token Bucket Algorithm&#xff09;正是這樣一種精妙…

【java】消息推送

文章目錄Java網頁消息推送解決方案 短輪詢、長輪詢、SSE、Websocket

STM32 | 有源蜂鳴器響,無源蜂鳴器播音樂

目錄 Overview 有源蜂鳴器 無源蜂鳴器 有源蜂鳴器控制 GPIO配置 控制程序 無源蜂鳴器控制 反轉GPIO控制 GPIO配置 控制接口 PWM控制 GPIO配置 控制函數 改變頻率播音樂 原理 1. 頻率決定音調 2. 占空比決定音量 GPIO初始化 結構體定義和音符頻率表 播放接口 …

第十四章 gin基礎

文章目錄Gin快速搭建一個web服務Gin數據交互JSON串內容規范Gin使用結構體返回數據給前端Gin配置POST類型的路由Gin獲取GET請求參數Gin獲取POST請求參數-form-data類型Gin獲取POST請求參數-JSON類型Gin獲取參數綁定至結構體Gin快速搭建一個web服務 下載包 \\新建一個文件&…

Baumer工業相機堡盟工業相機如何通過YoloV8的深度學習模型實現PCB的缺陷檢測(C#代碼,UI界面版)

Baumer工業相機堡盟工業相機如何通過YoloV8的深度學習模型實現PCB的缺陷檢測&#xff08;C#代碼&#xff0c;UI界面版&#xff09;工業相機使用YoloV8模型實現PCB的缺陷檢測工業相機實現YoloV8模型實現PCB的缺陷檢測的技術背景在相機SDK中獲取圖像轉換圖像的代碼分析工業相機圖…

【Vivado那些事兒】AMD-XILINX 7系列比特流加密

前提&#xff1a;加密有風險&#xff0c;操作需謹慎前言在許多項目中&#xff0c;經過漫長的等待&#xff0c;我們的 FPGA 設計終于可以投入現場部署了。前期的資金的投入及知識產權的保護&#xff0c;我們需要對現場部署的 FPGA 進行比特流保護以防止逆向工程和未經授權的重復…

RK3588 安卓adb操作

adb&#xff08;Android Debug Bridge&#xff09;是一個用于與安卓設備進行通信和控制的工具。adb可以通過USB或無線網絡連接安卓設備&#xff0c;執行各種命令&#xff0c;如安裝和卸載應用&#xff0c;傳輸文件&#xff0c;查看日志&#xff0c;運行shell命令等。adb是安卓開…

【華為機試】70. 爬樓梯

文章目錄70. 爬樓梯描述示例 1示例 2提示解題思路核心分析問題建模算法實現方法1&#xff1a;動態規劃&#xff08;標準解法&#xff09;方法2&#xff1a;空間優化動態規劃&#xff08;最優解&#xff09;方法3&#xff1a;遞歸 記憶化方法4&#xff1a;數學公式&#xff08;…

山東大學軟件學院面向對象期末復習

面向對象 文章目錄面向對象04 類封裝接口 抽象類05 消息&#xff0c;實例化&#xff0c;靜態變量方法消息動/靜態類型語言對象創建類及實例具有下面特征對象數組的創建靜態數據成員構造函數06_0 繼承繼承是向下傳遞的JAVA為什么不支持多重繼承繼承的形式特殊化繼承替換原則規范…

讓 Windows 用上 macOS 的系統下載與保姆級使用教程

模擬蘋果桌面軟件下載&#xff1a;https://xpan.com.cn/s/8NFAGT 還記得 Windows 11剛發布時&#xff0c;很多人就說“果里果氣"的&#xff0c;但界面確實做的漂亮。 不知道現在有多少小伙伴正用著macOS&#xff0c;不過我敢確定&#xff0c;喜歡macOS的人絕對不少&#…