SpringBoot 整合 Redis,一篇解决“缓存”的所有问题!

前言

这篇博文我们介绍SpringBoot如何整合Redis来访问非关系型数据库,带你深入了解Redis的自动原理,并结合具体案例进行实操,分享所有的源码。

01 为什么选择Spring Data Redis?

Spring Data Redis是Spring Data家族中最重要的一分子,它提供了从Spring应用程序轻松配置并访问Redis的功能。它提供了用于与存储交互的低级和高级抽象,使用户摆脱了对基础设施的担忧。

Spring Framework 是领先的全栈 Java/JEE 应用程序框架。它通过使用依赖注入、AOP 和可移植服务抽象提供了一个轻量级容器和一个非侵入式编程模型。

Spring Data Redis (SDR) 框架通过 Spring 出色的基础架构支持消除了与存储交互所需的冗余任务和样板代码,从而可以轻松编写使用 Redis 键值存储的 Spring 应用程序。

image.png

02 Spring Boot整合Redis

2.1 导入依赖项

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

自动引入的依赖,如图所示:

image.png

2.2 自动配置原理

自动配置类RedisAutoConfiguration

image.png
  • RedisProperties属性类,用于对Redis的基本属性配置
  • LettuceConnectionConfiguration、JedisConnectionConfiguration,Redis的客户端类型,其中配置了连接工厂,连接池等,默认为Lettuce,底层引入了Lettuce客户端jar包
  • 自动注入了RedisTemplate**<Object, **Object> : xxxTemplate;自动注入了StringRedisTemplate;k:v都是String

底层只要我们使用StringRedisTemplate、RedisTemplate就可以操作redis

2.3 默认整合Lettuce

2.3.1 添加配置

server:
  port: 8083

spring:
  application:
    name: springboot-redis
  redis:
    # Redis服务器地址
    host: localhost
    # Redis服务器连接端口
    port: 6379
    # Redis服务器连接密码(默认为空)
    password:
    # Redis数据库索引(默认为0)
    database: 0
  # 连接超时时间(毫秒)
    timeout : 300
    client-type: lettuce #切换jedis客户端,改成jedis
    lettuce: #切换jedis客户端,改成jedis
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池中的最小空闲连接
        min-idle: 0

2.4 切换至Jedis

2.4.1 导入jar

<!--导入jedis-->        
<dependency>            
    <groupId>redis.clients</groupId>            
    <artifactId>jedis</artifactId>        
</dependency>

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

2.5 配置序列化方式

RedisTemplate默认的序列化方式为JdkSerializationRedisSerializer,会把对象序列化存储到Redis中(二进制形式),StringRedisTemplate的默认序列化方式为StringRedisSerializer。绝大多数情况下,不推荐使用 JdkSerializationRedisSerializer 进行序列化,主要是不方便人工排查数据。所以我们需要切换序列化方式。

Spring Data底层为我们实现了七种不同的序列化方式,大家可以根据需要进行选择,如下图所示:

image.png

我们以Jackson2JsonRedisSerializer为例,展示如何切换序列化方式。

@Configuration
public class RedisConfig {

    /**
     * 默认是JDK的序列化策略,这里配置redisTemplate采用的是Jackson2JsonRedisSerializer的序列化策略
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用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默认采用的是String的序列化策略
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
        return stringRedisTemplate;
    }

}

03 代码示例

我为广大粉丝朋友提供了详细使用案例,以便更好地学习Redis。只展示其中一部分的代码,更加详细的代码,大家可以通过源码地址来查看。

@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() {
        //设置值
        stringRedisTemplate.opsForValue().set("String", "Mao");
        //获取值
        String string = stringRedisTemplate.opsForValue().get("String");
        System.out.println(string);

        //设置值且设置超时时间
        stringRedisTemplate.opsForValue().set("Middle", "Yu", 3, TimeUnit.MINUTES);
        String middle = stringRedisTemplate.opsForValue().get("Middle");
        System.out.println(middle);

        //删除数据
        Boolean isDelete = stringRedisTemplate.delete("String");
        Assert.isTrue(isDelete, "删除失败");
    }

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

    。。。。。。开源项目中还有内容哦。。。。。。

}

本文示例读者可以通过查看下面仓库中的项目,如下所示:

<module>springboot-redis</module>

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容

  • JAVA && Spring && SpringBoot2.x — 学习目录 Springboot抛弃了繁杂的xm...
    小胖学编程阅读 7,585评论 1 13
  • 前边我们已经学习了 Redis 的一些基本命令,以及通过 Jedis、Lettuce 来操作 Redis,但在实际...
    SheHuan阅读 6,611评论 0 7
  • SpringBoot 中除了了对常用的关系型数据库提供了优秀的自动化测试以外,对于很多 NoSQL 数据库一样提供...
    进击的程序猿呀阅读 240评论 0 0
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,535评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,187评论 4 8