SpringBoot 整合 Redis,一篇解決“緩存”的所有問題!

前言

這篇博文我們介紹SpringBoot如何整合Redis來訪問非關(guān)系型數(shù)據(jù)庫,帶你深入了解Redis的自動(dòng)原理,并結(jié)合具體案例進(jìn)行實(shí)操,分享所有的源碼。

01 為什么選擇Spring Data Redis?

Spring Data Redis是Spring Data家族中最重要的一分子,它提供了從Spring應(yīng)用程序輕松配置并訪問Redis的功能。它提供了用于與存儲(chǔ)交互的低級(jí)和高級(jí)抽象,使用戶擺脫了對(duì)基礎(chǔ)設(shè)施的擔(dān)憂。

Spring Framework 是領(lǐng)先的全棧 Java/JEE 應(yīng)用程序框架。它通過使用依賴注入、AOP 和可移植服務(wù)抽象提供了一個(gè)輕量級(jí)容器和一個(gè)非侵入式編程模型。

Spring Data Redis (SDR) 框架通過 Spring 出色的基礎(chǔ)架構(gòu)支持消除了與存儲(chǔ)交互所需的冗余任務(wù)和樣板代碼,從而可以輕松編寫使用 Redis 鍵值存儲(chǔ)的 Spring 應(yīng)用程序。

image.png

02 Spring Boot整合Redis

2.1 導(dǎo)入依賴項(xiàng)

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

自動(dòng)引入的依賴,如圖所示:

image.png

2.2 自動(dòng)配置原理

自動(dòng)配置類RedisAutoConfiguration

image.png
  • RedisProperties屬性類,用于對(duì)Redis的基本屬性配置
  • LettuceConnectionConfiguration、JedisConnectionConfiguration,Redis的客戶端類型,其中配置了連接工廠,連接池等,默認(rèn)為L(zhǎng)ettuce,底層引入了Lettuce客戶端jar包
  • 自動(dòng)注入了RedisTemplate**<Object, **Object> : xxxTemplate;自動(dòng)注入了StringRedisTemplate;k:v都是String

底層只要我們使用StringRedisTemplate、RedisTemplate就可以操作redis

2.3 默認(rèn)整合Lettuce

2.3.1 添加配置

server:
  port: 8083

spring:
  application:
    name: springboot-redis
  redis:
    # Redis服務(wù)器地址
    host: localhost
    # Redis服務(wù)器連接端口
    port: 6379
    # Redis服務(wù)器連接密碼(默認(rèn)為空)
    password:
    # Redis數(shù)據(jù)庫索引(默認(rèn)為0)
    database: 0
  # 連接超時(shí)時(shí)間(毫秒)
    timeout : 300
    client-type: lettuce #切換jedis客戶端,改成jedis
    lettuce: #切換jedis客戶端,改成jedis
      pool:
        # 連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
        max-active: 8
        # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)
        max-wait: -1
        # 連接池中的最大空閑連接
        max-idle: 8
        # 連接池中的最小空閑連接
        min-idle: 0

2.4 切換至Jedis

2.4.1 導(dǎo)入jar

<!--導(dǎo)入jedis-->        
<dependency>            
    <groupId>redis.clients</groupId>            
    <artifactId>jedis</artifactId>        
</dependency>

注意:配置基本同上,只需要將lettuce換成jedis即可。

2.5 配置序列化方式

RedisTemplate默認(rèn)的序列化方式為JdkSerializationRedisSerializer,會(huì)把對(duì)象序列化存儲(chǔ)到Redis中(二進(jìn)制形式),StringRedisTemplate的默認(rèn)序列化方式為StringRedisSerializer。絕大多數(shù)情況下,不推薦使用 JdkSerializationRedisSerializer 進(jìn)行序列化,主要是不方便人工排查數(shù)據(jù)。所以我們需要切換序列化方式。

Spring Data底層為我們實(shí)現(xiàn)了七種不同的序列化方式,大家可以根據(jù)需要進(jìn)行選擇,如下圖所示:

image.png

我們以Jackson2JsonRedisSerializer為例,展示如何切換序列化方式。

@Configuration
public class RedisConfig {

    /**
     * 默認(rèn)是JDK的序列化策略,這里配置redisTemplate采用的是Jackson2JsonRedisSerializer的序列化策略
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        //使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(默認(rèn)使用JDK的序列化方式)
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 配置連接工廠
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //使用StringRedisSerializer來序列化和反序列化redis的key值
        //redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
        // 值采用json序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /***
     * stringRedisTemplate默認(rèn)采用的是String的序列化策略
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
        return stringRedisTemplate;
    }

}

03 代碼示例

我為廣大粉絲朋友提供了詳細(xì)使用案例,以便更好地學(xué)習(xí)Redis。只展示其中一部分的代碼,更加詳細(xì)的代碼,大家可以通過源碼地址來查看。

@SpringBootTest
public class RedisApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    void testRedis(){
        ValueOperations<String, String> operations = redisTemplate.opsForValue();

        operations.set("hello","world");

        String hello = operations.get("hello");
        System.out.println(hello);
    }

    /**
     * 操作字符串
     */
    @Test
    public void testString() {
        //設(shè)置值
        stringRedisTemplate.opsForValue().set("String", "Mao");
        //獲取值
        String string = stringRedisTemplate.opsForValue().get("String");
        System.out.println(string);

        //設(shè)置值且設(shè)置超時(shí)時(shí)間
        stringRedisTemplate.opsForValue().set("Middle", "Yu", 3, TimeUnit.MINUTES);
        String middle = stringRedisTemplate.opsForValue().get("Middle");
        System.out.println(middle);

        //刪除數(shù)據(jù)
        Boolean isDelete = stringRedisTemplate.delete("String");
        Assert.isTrue(isDelete, "刪除失敗");
    }

    /**
     * 操作列表
     */
    @Test
    public void testList() {
        ListOperations listOp = redisTemplate.opsForList();
        //往 List 左側(cè)插入一個(gè)元素
        listOp.leftPush("nameList", "mike");
        listOp.leftPush("nameList", "kim");
        //往 List 右側(cè)插入一個(gè)元素
        listOp.rightPush("nameList", "jimmy");
        listOp.rightPush("nameList", "chuck");
        //List 大小
        Long size = listOp.size("nameList");
        //遍歷整個(gè)List
        List nameList1 = listOp.range("nameList", 0, size);
        System.out.println(JSON.toJSONString(nameList1));
        //遍歷整個(gè)List,-1表示倒數(shù)第一個(gè)即最后一個(gè)
        List nameList = listOp.range("nameList", 0, -1);
        System.out.println(JSON.toJSONString(nameList));
        //從 List 左側(cè)取出第一個(gè)元素,并移除
        Object name1 = listOp.leftPop("nameList", 200, TimeUnit.MILLISECONDS);
        System.out.println("is kim:" + name1.equals("kim"));
        //從 List 右側(cè)取出第一個(gè)元素,并移除
        Object name2 = listOp.rightPop("nameList");
        System.out.println("is chuck:" + name2.equals("chuck"));
    }

    。。。。。。開源項(xiàng)目中還有內(nèi)容哦。。。。。。

}

本文示例讀者可以通過查看下面?zhèn)}庫中的項(xiàng)目,如下所示:

<module>springboot-redis</module>

作者:程序猿小亮
原文鏈接:https://blog.csdn.net/jiuqiyuliang/article/details/118677483?spm=1001.2014.3001.5502

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • JAVA && Spring && SpringBoot2.x — 學(xué)習(xí)目錄 Springboot拋棄了繁雜的xm...
    小胖學(xué)編程閱讀 7,918評(píng)論 1 13
  • 前邊我們已經(jīng)學(xué)習(xí)了 Redis 的一些基本命令,以及通過 Jedis、Lettuce 來操作 Redis,但在實(shí)際...
    SheHuan閱讀 7,049評(píng)論 0 7
  • SpringBoot 中除了了對(duì)常用的關(guān)系型數(shù)據(jù)庫提供了優(yōu)秀的自動(dòng)化測(cè)試以外,對(duì)于很多 NoSQL 數(shù)據(jù)庫一樣提供...
    進(jìn)擊的程序猿呀閱讀 351評(píng)論 0 0
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,820評(píng)論 28 54
  • 信任包括信任自己和信任他人 很多時(shí)候,很多事情,失敗、遺憾、錯(cuò)過,源于不自信,不信任他人 覺得自己做不成,別人做不...
    吳氵晃閱讀 6,360評(píng)論 4 8

友情鏈接更多精彩內(nèi)容