SpringBoot(七) - Redis 緩存

来源:https://www.cnblogs.com/xiaoqigui/archive/2022/10/18/16803709.html
-Advertisement-
Play Games

1、五大基本數據類型和操作 1.1 字元串-string | 命令 | 說明 | | | | | set key value | 如果key還沒有,那就可以添加,如果key已經存在了,那會覆蓋原有key的值 | | get key | 如果key還沒有,獲取為(nil),代表key沒有被使用,如果k ...


1、五大基本數據類型和操作

1.1 字元串-string

命令 說明
set key value 如果key還沒有,那就可以添加,如果key已經存在了,那會覆蓋原有key的值
get key 如果key還沒有,獲取為(nil),代表key沒有被使用,如果key存在,可以獲取對應key的值
exists key 判斷某個key是否存在,返回Integer值1 代表存在,如果 exists car2 則返回0,不存在
move key db 將當前資料庫存在的鍵值移動到其它資料庫,其中db是資料庫的序號
expire key 秒鐘 為已經存在的key設置過期時間,註意過期之後,從記憶體中去掉了,是get不到的
ttl key 查看還有多少秒過期,-1表示永不過期,-2表示已過期
type key 命令用於返回 key 所儲存的值的類型
del key 根據key值刪除
append key value 根據key將其值進行字元串拼接
strlen key 根據key獲取其值的字元串長度,位元組數
incr key 對key對應數值進行加一操作,對應的字元串值必須是數值
decr key 對key對應數值進行減一操作
incrby key 數值 對key對應數值按照指定的值進行遞增
decrby key 數值 對key對應數值按照指定的值進行遞減
getrange key 起始位置 結束位置 獲取指定區間內的值,類似between。。。and的關係,起始位置為0,結束位置為-1 就是返回所有
setrange key 起始位置 具體值 設置指定區間內的值,具體值會從起始位置開始覆蓋
setex key 過期秒值 真實值 設置帶過期時間的key,動態設置。
setnx key value 只有在 key 不存在時,才會設置 key 的值,如果已經存在了,不覆蓋,設置不了;
setnx key value 如果返回0 代表沒有設置成功,key對應值已經存在,如果返回1代表設置成功;這個就是redis的分散式鎖命令,很重要;
mset key1 val1 key2 val2 .... 同時設置一個或多個 key-value 對
mget key1 key2 key3 .... 獲取所有(一個或多個)給定 key 的值。
msetnx key1 val1 key2 val2 ..... 同時設置一個或多個 key-value 對,當且僅當所有給定 key 都不存在

1.2 列表-list

list操作起來類似於棧;

命令 說明
lpush key val1 val2 val3 .... 從左側開始存放元素,先進後出
lrange key 起始位置 結束位置 從左側開始,指定範圍獲取元素,-1代表所有
rpush key val1 val2 val3 .... 從右側開始存放元素,先進先出
lpop key 從左側一次取出一個元素
rpop key 從右側一次取出一個元素
lindex key index 按照索引下標獲得元素(從左到右,左下標從0開始,如果是-1代表最後一個,-2代表倒數第二個)
llen key 獲取集合元素個數
lrem key 個數 具體的值 從左往右刪除指定個數等於具體值的元素,返回的值為實際刪除的數量,個數0,表示刪除全部給定的值
ltrim key 開始index 結束index 截取指定範圍的值後再賦值給key
rpoplpush 源列表 目的列表 移除列表的最後一個元素,並將該元素添加到另一個列表並返回
lset key index value 將key集合中的指定下標位置值改為value
linsert key before/after 值1 值2 在list某個已有 值1 的前後再添加具體 值2

小結:

  1. 它是一個字元串鏈表,left、right都可以插入添加;
  2. 如果鍵不存在,創建新的鏈表;
  3. 如果鍵已存在,新增內容;
  4. 如果值全移除,對應的鍵也就消失了;
  5. 鏈表的操作無論是頭和尾效率都極高,但假如是對中間元素進行操作,效率就很慘淡了;

1.3 集合-set

命令 說明
sadd key val1 val2 ... 集合set中添加元素,如果有重覆元素會自動去除
smembers key 查看集合中的元素
sismember key val 判斷val是否在set集合中,如果在返回1 ,不在返回0
scard key 獲取集合裡面的元素個數
srem key value 刪除集合中元素
srandmember key 某個整數 隨機出幾個數,如果超過最大數量就全部取出
srandmember key 某個整數 如果寫的值是負數,比如-3 ,表示需要取出3個,但是可能會有重覆值。
spop key 隨機出棧
smove key1 key2 將key1里的某個值賦給key2
sdiff key1 key2 在第一個set裡面而不在後面任何一個set裡面的項
sinter key1 key2 在兩個set中都有的值的交集返回
sunion key1 key2 在兩個set中所有的值的集合返回,會自動排除重覆

1.4 鍵值對-hash

K V模式不變,但V是一個鍵值對;

命令 說明
hset 父key 子key 子value 將父key,增加子鍵值對,類似屬性
hget 父key 子key 獲取父key,某個子key的值,獲取屬性值
hmset 父key 子key1 子val1 子key2 子val2 .... 批量添加屬性
hmget 父key 子key1 子key... 批量獲取屬性
hgetall 父key 批量獲取屬性及值
hdel 父key 子key 刪除子key屬性及值
hlen 父key 返回父key中的子key個數,相當於java實體的屬性個數
hexists 父key 子key 判斷父key中是否包含某個子key,結果為1,代表存在
hkeys 父key 獲取父key中所有的子key
hvals 父key 獲取父key中的所有的子val
hincrby 父key 子key 值 給指定的子key值增加固定的值
hincrbyfloat 父key 子key 值 給有指定key的值增加小數
hsetnx 父key 子key 子val 如果子key存在則失敗,如果不存在則賦值

1.5 有序集合-zset

在set基礎上,加一個score值。之前set是k1 v1 v2 v3,現在zset是k1 score1 v1 score2 v2;

命令 說明
zadd key score1 val1 score2 val2 score3 val3 ... 有序集合添加帶score值的元素
zscore key val 獲取集合中某個值對應score值
zrange key 0 -1 [withscores] zrange zset1 0 -1 ,結果為所有的值,不帶分數;如:zrange zset1 0 -1 ,結果為所有的值,不帶分數
zrange zset1 0 -1 withscores 結果為所有的值和分數
zrangebyscore key 開始score 結束score 獲取score值在開始score-結束score之間的元素
zrangebyscore zset1 10 40 獲取score值在10-40之間的元素,包含10和40
zrangebyscore zset1 10 (40 不包含40值;( 的含義是不包含
zrangebyscore zset1 (10 (40 不包含10,40值
zrangebyscore zset1 10 50 limit 2 2 limit 結果的起始下標,獲取的個數;limit 含義是限制獲取的條數,相當於mysql的分頁;
zrem key 某score下對應的value值 刪除元素
zcard key 獲取key對應的值的個數;註意score 和 value是一個整體
zcount key score區間 獲取分值區間內元素個數
zrank key values值 獲得下標值
zscore key 對應value值 獲得value對應分數
zrevrank key value值 逆序獲得對應逆序的下標值
zrevrange key 起始下標,結束下標 將之前順序進行倒序
zrevrangebyscore key 結束score 開始score 根據score值輸出元素
zincrby key 增加分值 value值 給對應的值增加score值

2、Redis整合

2.1 spring-boot-starter-data-redis 依賴

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

2.2 redis配置

#埠號
server:
  port: 8096

# redis配置
spring:
  redis:
    host: 127.0.0.1 #如果是redis遠程伺服器,此處redis伺服器ip地址
    port: 6379 #預設埠
#    database: 0 #指定redis資料庫,預設是0
#    password:   # 密碼有就寫,沒有就省略

2.3 SpringBoot框架自動配置的redisTemplate

2.3.1 清空資料庫

//自動裝配  SpringBoot框架自動配置的redisTemplate
@Autowired
private RedisTemplate<Object,Object> redisTemplate;

//基於SpringBoot框架自動配置的redisTemplate,操作redis緩存
//獲取連接
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//清空資料庫中的所有數據
log.info("清空資料庫中的所有數據");
connection.flushDb();

2.3.2 添加數據

//程式中,添加數據據到redis
log.info("------ 基於SpringBoot框架自動配置的redisTemplate 添加數據 ------");
redisTemplate.opsForValue().set("kh96_class_name","KGC_KH96");
redisTemplate.opsForValue().set("student_num",19);

2.3.3 獲取數據

//程式中,從redis獲取數據
log.info("------ 基於SpringBoot框架自動配置的redisTemplate 獲取數據 ------");
log.info("****** 根據 班級的key:{},獲取班級名稱:{} ******","kh96_class_name",redisTemplate.opsForValue().get("kh96_class_name"));
log.info("****** 根據 班級的key:{},獲取班級人數:{} ******","student_num",redisTemplate.opsForValue().get("student_num"));

2.3.4 修改值 (出現錯誤)

//程式中,基於SpringBoot框架自動配置的redisTemplate,操作redis緩存,存在問題
//場景:對班級人數進行增減操作,比如將班級人數,增加10
log.info("------ 基於SpringBoot框架自動配置的redisTemplate 操作數據 ------");
redisTemplate.opsForValue().increment("student_num",10);
//直接報錯,會報500異常: redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of range
//原因,通過系統預設的 redisTemplate,存放key和value值時,會自動使用Object類的序列化和反序列化,導致redis中真實存放的數據不是原始值,而是序列化後的值

數據結果:

2.4 自定義redisTemplate

2.4.1 fastjson 依賴

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

2.4.2 自定義redisTemplate 配置類

//Redis自定義配置類,實現一個自定義序列化方式的 redisTemplate,提緩緩掉預設自動配置的 redisTemplate,實現String類型任意類型的value
@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 自定義redisTemplate的模板對象
        RedisTemplate<String, Object> template = new RedisTemplate<>();

        // 設置連接工廠
        template.setConnectionFactory(redisConnectionFactory);

        //由於要通過程式操作遠程的redis資料庫,必須支持序列化,才可以讓程式中的數據,在網路中傳輸
        //定義String類型的序列化方式
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // 定義fastjson序列化方式,可以序列化任何對象
        FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);

        // 需改為新的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        template.setValueSerializer(fastJsonRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        template.setHashValueSerializer(fastJsonRedisSerializer);

        // 初始化為新的模板
        template.afterPropertiesSet();

        return template;
    }

}

2.4.3 使用自定義redisTemplate 重新操作數據

//自動裝配自定義 redisTemplate 
@Autowired
private RedisTemplate<String,Object> redisTemplate;

//其他代碼不變

操作結果:

2.5 自定義redisUtils工具類

2.5.1 自定義redisUtils工具類

---> RedisUtil 工具類

2.5.2 使用自定義redisTemplate和redisUtils工具類

@GetMapping("/testRedisUtils")
public String testSpringBootRedisUtils(){

    //基於自定義的redisTemplate 和 RedisUtils 工具類,操作redis緩存
    //程式中,添加數據據到redis
    log.info("------ 基於自定義的redisTemplate 和 RedisUtils 工具類 添加數據 ------");
    redisUtils.set("kh96_class_name_utils","KGC_KH96");
    redisUtils.set("student_num_utils",19);

    //程式中,從redis獲取數據
    log.info("------ 基於自定義的redisTemplate 和 RedisUtils 工具類 獲取數據 ------");
    log.info("****** 根據 班級的key:{},獲取班級名稱:{} ******","kh96_class_name_utils",redisUtils.get("kh96_class_name_utils"));
    log.info("****** 根據 班級的key:{},獲取班級人數:{} ******","student_num_utils",redisUtils.get("student_num_utils"));

    //程式中,基於SpringBoot框架自動配置的redisTemplate,操作redis緩存
    //場景:對班級人數進行增減操作,比如薑班級人數,增加10
    log.info("------ 基於自定義的redisTemplate 和 RedisUtils 工具類 操作數據 ------");
    redisUtils.incr("student_num_utils",10);

    return "工具類 RedisUtils  操作 redis 成功!";

}

2.5.3 程式中如何存放對象到 redis

核心思想:一般都是薑對象轉換為json字元串,存入redis,獲取對象數據,就先獲取json字元串,再轉換為對應對象即可;

@GetMapping("/testRedisUtils")
public String testSpringBootRedisUtils(){

    //程式中如何存放對象到 redis
    //核心思想:一般都是薑對象轉換為json字元串,存入redis,獲取對象數據,就先獲取json字元串,再轉換為對應對象即可

    //模擬用戶登錄成功後,將用戶信息存入redis中,方便後續從redis中獲取用戶信息
    User loginUser = User.builder().userId(1001).userName("KH96").userTel("135012030404").build();

    //直接將對象存入redis即可
    log.info("------ 基於自定義的redisTemplate 和 RedisUtils 工具類 存儲對象 ------");
    //自動把實體,通過fastjson的序列化方式,轉發為JSON字元串存儲
    redisUtils.set(loginUser.getUserId().toString(),loginUser);

    //模擬獲取登錄用戶信息,直接從redis獲取存入的JSON字元串,轉換為目標用戶對象
    User realUser = JSON.parseObject(redisUtils.get(loginUser.getUserId().toString()).toString(),User.class);

    log.info("------ 基於自定義的redisTemplate 和 RedisUtils 工具類獲取對象:{} ",realUser);

    return "工具類 RedisUtils  操作 redis 成功!";

}

數據結果:





您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 您好,我是湘王,這是我的博客園,歡迎您來,歡迎您再來~ 為瞭解決標準Java I/O令人難以忍受的效率問題,從JDK1.4開始,NIO出現了(Non-blocking I/O,官方稱之為New I/O)。NIO不但新增加了許多全新的類,而且還對原來的很多類進行了改寫。之所以是NIO,是因為使用它的場 ...
  • 1.題目 給你一個整數數組 nums ,請你找出一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。 子數組 是數組中的一個連續部分。 示例 1: 輸入:nums = [-2,1,-3,4,-1,2,1,-5,4] 輸出:6 解釋:連續子數組 [4,-1,2,1] 的和最大,為 6 ...
  • mybatis-plugin插件執行原理 今天主要是在看mybatis的主流程源碼,其中比較感興趣的是mybatis的plugin功能,這裡主要記錄下mybatis-plugin的插件功能原理。 plugin集合列表:在構建SqlSessionFactory時,通過解析配置或者plugin-bean ...
  • 什麼是集合? 集合就是由若幹個確定的元素所構成的整體。例如,5只小兔構成的集合: 在數學中,我們經常遇到集合的概念。例如: ● 有限集合 ○ 一個班所有的同學構成的集合; ○ 一個網站所有的商品構成的集合; ● 無限集合 ○ 整數集合 ○ 有理數集合 ○ 實數集合 為什麼要在電腦中引入集合呢? 這 ...
  • 平常我們爬的評論、彈幕等等,數量又多又密,根本看不過來,這時候數據分析的作用來了,今天我們就試試用Python根據這些數據,來繪製詞雲圖進行熱詞分析。 知識點 文件讀寫 基礎語法 字元串處理 文件生成 數據構建 代碼展示 # 導入系統包 import platform from flask impo ...
  • 1、print() print()函數的作用是輸出數據到控制台,就是列印在你能看到的界面上。 2、return return語句[表達式]退出函數,選擇性地向調用方返回一個表達式。不帶參數值的return語句返回None。 return作為腳本單獨運行時則需要print函數才能顯示,但是在交互模式下 ...
  • 使用這種分頁方式,好像是比jpa或者MyBatis自帶的分頁工具有更好的性能和安全性。 需要接收的參數 public ApiResponse getBlackList( @RequestParam(name = "pageSize", required = false) Integer pageSi ...
  • R語言之旅。原書P88頁案例3-3解答。根據描述統計量有什麼見解、本國學生和國外學生學費差別、工作經驗要求與否與起薪差別、英語測試要求與否與起薪差別、起薪與學費關係。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...