• springboot实战(八)之整合redis


    目录

    序言: 

    环境:

    依赖:

    配置:

    测试:

    redis序列化配置:

    连接池:


    序言: 

    Redis是我们Java开发中,使用频次非常高的一个nosql数据库,数据以key-value键值对的形式存储在内存中。它的使用场景多样可以做缓存,分布式锁,自增序列等,且数据类型丰富,支持5中数据类型的存储,分别是String、has、list、set、zset,还有单线程作业速度超快。

    使用redis的方式也和我们使用关系型数据库的方式一样,首先我们要在自己的本机电脑或者服务器上安装一个redis的服务器,然后在我们的项目中通过java进行其客户端集成,最后通过java集成的客户端完成对redis的增删改查操作。

    Redis的Java客户端类型常见的有jedis, redission,lettuce等,所以我们在集成的时候,可以选择直接集成这些原生客户端。但是在springBoot中更常见的方式是集成spring-data-redis,这是spring提供的一个专门用来操作redis的项目,封装了对redis的常用操作,里边主要封装了jedis和lettuce两个客户端,但是默认使用的是lettuce客户端。

    环境:

    版本:spring boot:2.7.15

    jdk:1.8

    redis:安装最新的redis服务端就OK了

    依赖:

    由于springboot项目已经集成了各种中间件的starter,所以这里我们直接引用redis的starter依赖就行了。

    1. <!-- redis 依赖 -->
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter-data-redis</artifactId>
    5. </dependency>

    配置:

    依赖添加完后,我们需要在yml文件中进行redis链接配置。

    1. spring:
    2. redis:
    3. host: localhost
    4. #有密码就写,没有就注释掉
    5. #password:
    6. port: 6379
    7. database: 1

    完整的配置信息:

    1. server:
    2. port: 8081
    3. spring:
    4. datasource:
    5. driver-class-name: com.mysql.cj.jdbc.Driver
    6. url: jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&useSSL=false&serverTimezone=Asia/Shanghai
    7. username: root
    8. password: root
    9. redis:
    10. host: localhost
    11. #有密码就写,没有就注释掉
    12. #password:
    13. port: 6379
    14. database: 1
    15. #这里配置日志生效文件,用于多环境部署时切换(通常部署会有三个环境:线上、测试、开发)
    16. logging:
    17. config: classpath:log4j2/log4j2-dev.yml

    测试:

    配置完以上信息后,我们可以创建一个测试类进行测试。

    1. package com.iterge.iterge_pre.redis;
    2. import org.junit.jupiter.api.Test;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.boot.test.context.SpringBootTest;
    5. import org.springframework.data.redis.core.RedisTemplate;
    6. /**
    7. * @author liuph
    8. * @date 2023/9/26 14:36:45
    9. */
    10. @SpringBootTest
    11. public class RedisTest {
    12. @Autowired
    13. private RedisTemplate redisTemplate;
    14. @Test
    15. public void stringTest(){
    16. redisTemplate.opsForValue().set("name","hi redis!");
    17. }
    18. @Test
    19. public void getStringTest(){
    20. Object name = redisTemplate.opsForValue().get("name");
    21. System.out.println(name);
    22. }
    23. }

     

    图上我们可以看到获取的value的时候,返回值类型是object,控制台打印的时候信息也是正确的。

    但是我们通过终端连接redis后进行信息查看,发现get name是没有数据的,是不是很奇怪,我们明明插入进去了并且在程序中查了出来怎么就没有呢?然后我们用keys *name*,命令模糊查找下我们的key,发现有个"\xac\xed\x00\x05t\x00\x04name",然后get "\xac\xed\x00\x05t\x00\x04name"发现,好像是我们我们设置的“hi redis”,图如下。但是为什么key和value都有个前缀?上述涉及到一切问题这就涉及到redis的序列化操作了,接着往下看序列化配置和描述。

    命令:

    1. #连接redis的客户端命令
    2. redis-cli
    3. #选择使用的数据库,因为我们用的是1,所以是select 1
    4. select 1

    redis序列化配置:

    Redis的序列化是我们在使用RedisTemplate的过程中非常需要注意的事情。上面的案例中,其实我们并没有特殊设置redis的序列化方式,那么它其实使用的是默认的序列化方式。RedisTemplate这个类的泛型是,也就是为什么刚刚提到返回值类型是Object了,它写入的其实是个对象。

    什么是redis的序列化呢?这个对象采取什么方式序列化存入内存中就是它的序列化方式。

    就是我们把对象存入到redis中到底以什么方式存储的,可以是二进制数据,可以是xml也可以是json。比如说我们经常会将POJO对象存储到 Redis 中,一般情况下会使用 JSON 方式序列化成字符串,存储到 Redis 中 。

    Redis本身提供了一下一种序列化的方式:

    • GenericToStringSerializer: 可以将任何对象泛化为字符串并序列化
    • JacksonJsonRedisSerializer: 序列化object对象为json字符串
    • Jackson2JsonRedisSerializer: 跟JacksonJsonRedisSerializer实际上是一样的
    • JdkSerializationRedisSerializer: 序列化java对象,默认序列化方式
    • StringRedisSerializer: 简单的字符串序列化

    如果我们存储的是String类型,默认使用的是StringRedisSerializer 这种序列化方式。如果我们存储的是对象,默认使用的是 JdkSerializationRedisSerializer,也就是Jdk的序列化方式(通过ObjectOutputStream和ObjectInputStream实现,缺点是我们无法直观看到存储的对象内容)。

    配置:

    1. package com.iterge.iterge_pre.config;
    2. import com.fasterxml.jackson.annotation.JsonAutoDetect;
    3. import com.fasterxml.jackson.annotation.JsonTypeInfo;
    4. import com.fasterxml.jackson.annotation.PropertyAccessor;
    5. import com.fasterxml.jackson.databind.ObjectMapper;
    6. import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
    7. import org.springframework.context.annotation.Bean;
    8. import org.springframework.context.annotation.Configuration;
    9. import org.springframework.data.redis.connection.RedisConnectionFactory;
    10. import org.springframework.data.redis.core.RedisTemplate;
    11. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    12. import org.springframework.data.redis.serializer.StringRedisSerializer;
    13. /**
    14. * @author liuph
    15. * @date 2023/9/26 15:47:09
    16. */
    17. @Configuration
    18. public class RedisConfig {
    19. @Bean(name = "redisTemplate")
    20. public RedisTemplate getRedisTemplate(RedisConnectionFactory factory) {
    21. RedisTemplate redisTemplate = new RedisTemplate<>();
    22. redisTemplate.setConnectionFactory(factory);
    23. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    24. ObjectMapper objectMapper = new ObjectMapper();
    25. objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    26. // 方法过期,改为下面代码
    27. //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    28. objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
    29. ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
    30. jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
    31. // key的序列化类型
    32. redisTemplate.setKeySerializer(new StringRedisSerializer());
    33. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    34. // value的序列化类型
    35. redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    36. redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
    37. redisTemplate.afterPropertiesSet();
    38. return redisTemplate;
    39. }
    40. }

     测试:

    如下图所示可以看出是,redisTemplate中的key和value的序列化方式已经改为我们所设置的。

    再通过终端查看设置结果,key:user设置成功,并且get user能正常获取到存储的value。

    连接池:

    在生产环境中我们往往需要配置redis连接池,目的是为了增加对于redis数据库连接的管理,提升访问的效率,也保证了对资源的合理利用。

    由于我们使用的是默认的客户端lettuce,那么我们就用lettuce连接池,如果大家想使用jedis连接池,改成jedis连接池就OK,并且需要引入jedis核心jar包。

    lettuce连接池配置信息如下:

    首先需要添加一个连接池连接依赖,不加依赖配置不会生效,切记哦~

    1. org.apache.commons
    2. commons-pool2
    1. spring:
    2. redis:
    3. host: localhost
    4. #有密码就写,没有就注释掉
    5. #password:
    6. port: 6379
    7. database: 1
    8. lettuce:
    9. pool:
    10. #连接池同时能维持的最大连接数
    11. max-active: 16
    12. #最多维持多少个空闲连接
    13. max-idle: 16
    14. #最少维持多少个空闲连接
    15. min-idle: 4

    配置好以上信息就OK,运行程序,查看连接池配置是否生效,如图,如果有以下信息说明配置已经生效,配置完成:

     注意如果不添加上面的链接池依赖,redisTemplate运行时是没有连接池信息的,如下图:


     创作不易,您的鼓励是我前进的动力,如果有用记得点点关注哈~

  • 相关阅读:
    [iOS开发]-暑期二-3GShare-协议传值的多方面运用
    项目安全性与权限管理实践与探讨
    Angular组件间传值有哪几种方法?
    jQuery学习:内置动画 淡出/淡入 展开/收缩 显示/隐藏
    使用Vscode创建一个C_Hello程序
    FLUENT网格质量
    嵌入式分享合集19
    物联网开发笔记(45)- 使用Micropython开发ESP32开发板之控制红外传感器
    SpringBoot学习笔记-创建个人中心页面(上)
    【WINDOWS / DOS 批处理】if命令参数详解(二)
  • 原文地址:https://blog.csdn.net/it_erge/article/details/133309560