首页 > 数据库 >spring-boot-data Redis 使用

spring-boot-data Redis 使用

时间:2023-06-09 18:45:14浏览次数:61  
标签:spring boot public objectMapper new Redis 序列化 class redisTemplate

spring-boot-data redis

Spring Boot 提供了 Redis 集成启动器(Starter),依赖于 spring-data-redis 和 lettuce 库。 spring-data-redis:对 Reids 底层开发包高度封装,让开发者对 Redis 的 CRUD 操作起来更加方便。

创建工程

  • 导入相关依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

引入 spring-boot-starter-data-redis 依赖就可以快速帮助我们操作 Redis

配置资源 resource/application.yml

  • 配置 Redis 连接源和 Lecture 相关信息
spring:
  datasource:
    url: jdbc:mysql://主机地址:3306/stu?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
  redis:
    host: 主机地址
    port: 端口号
    password: 密码
    lettuce:
      pool:
        max-active: 20 # 连接池最大连接数
        max-wait: 1 # 最大阻塞等待时间
        max-idle: 5 # 最大
        min-idle: 0 # 连接池的最小空闲连接
      shutdown-timeout: 100

配置 jackson

  • 配置查询转换异常 和SON转化为对象,会转化成Map类型相关问题
 @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 自定义类型转换器
        SimpleModule simpleModule = new SimpleModule();
        final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
        // 时间转换 module - 用户 LocalDateTime 日期类型的序列化和反序列化
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        // 配置 LocalDateTime 的序列化规则和格式化规则
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
//        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
//        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        // 添加自定义序列化器
        simpleModule.addSerializer(Money.class , new MoneySerializer());
        simpleModule.addDeserializer(Money.class , new MoneyDeserializer());
        objectMapper.registerModule(simpleModule);
        objectMapper.registerModule(javaTimeModule);
        // 配置查询缓存转换异常
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 必须设置,否则无法将JSON转化为对象,会转化成Map类型
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);
        return objectMapper;
    }
  • 配置序列化 Module 可以适配非基本类型的序列化如 LocalDateTimeorg.joa.Money

1、实现 class 的相关序列化和反序列化器
2、在相关 Module 进行序列化器的注册,如果没有相关的 Module 可以采用 SimpleModule 进行相关的序列化器和反序列化器的添加

3、序列化通过实现 StdSerializer 或者 JsonSerializer 进行自定义序列化的实现

// 标记成 JSON 的 Component
@JsonComponent 
public class MoneySerializer extends StdSerializer<Money> {
    public MoneySerializer() {
        super(Money.class);
    }

    @Override
    public void serialize(Money money, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeNumber(money.getAmountMinor());
    }
}

4、反序列化通过实现 MoneyDeserializer 或者 JsonDeserializer 进行自定义反序列化的实现

@JsonComponent
public class MoneyDeserializer extends StdDeserializer<Money> {
    public MoneyDeserializer() {
        super(Money.class);
    }

    @Override
    public Money deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        return Money.ofMinor(CurrencyUnit.of("CNY"), p.getLongValue());
    }
}

5、序列化会对 Money 的内容进行相关的改变

实现自定义序列化器

  • 通过实现 RedisSerializer 进行自定义 Redis 序列化器的实现,同时实现 InitializingBean 接口适配 Spring
public class RedisKeySerializer implements InitializingBean, RedisSerializer<String> {

    private final String keyPrefix = "test:";

    private final String charsetName = "UTF-8";

    private Charset charset;

    @Override
    public byte[] serialize(String key) throws SerializationException {
        String builderKey = keyPrefix + key;
        return builderKey.getBytes();
    }

    @Override
    public String deserialize(byte[] bytes) throws SerializationException {
        return new String(bytes, charset);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        charset = Charset.forName(charsetName);
    }
}
  • 注意:实现 InitializingBean 会让 RedisKeySerializer 在注册到 Spring 容器时初始化相关的 Charset 字符集

配置 RedisConfig

1、为了解决 RedisTemplate<K , V> 在操作时的序列化器问题,需要把 setKeySerializer 设置成 RedisKeySerializer 如果不设置会把 K 进行序列化后在进行相关的存储操作,此时 K 就是 K 序列化后的值
2、配置 Redis 序列化器添加之前我们配置的 ObjectMapper 对象从而解决 1、配置查询缓存转换异常;2、JSON转化为对象,会转化成Map类型 两个问题

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        // 创建模板
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 设置序列化工具
//
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//        // key和 hashKey采用 string序列化
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        redisTemplate.setKeySerializer(new RedisKeySerializer());
        redisTemplate.setHashKeySerializer(new RedisKeySerializer());
//        // value和 hashValue采用 JSON序列化

        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
  • StringRedisTemplate
    @Bean(name = "stringStringRedisTemplate")
    public StringRedisTemplate stringStringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();

        stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        stringRedisTemplate.setKeySerializer(new RedisKeySerializer());
        stringRedisTemplate.setHashKeySerializer(new RedisKeySerializer());
        stringRedisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        stringRedisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        stringRedisTemplate.afterPropertiesSet();
        return stringRedisTemplate;
    }

注意事项

1、StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
2、RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
3、两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
4、操作简单的数据可以采用 StringRedisTemplate 可以减少序列化的开销,操作复杂的数据类型时可以采用 RedisTemplate
5、StringRedisTemplate 存储非基本类型时需要把 class 转换成 JSONString

  User user = new User();

        user.setAge(20);
        user.setName("231213");
        user.setDateTime(LocalDateTime.now());

        String key = StrUtil.builder().append(RedisConstants.USER_PREFIX).append(user.getName()).toString();
        stringRedisTemplate.opsForValue().set(key ,JSONUtil.toJsonStr(user));

6、获取时如果获取的是非基本类型数据需要通过 FASTJSON2 的 JSON.parseObject(vaue , clazz); 进行对象转换

标签:spring,boot,public,objectMapper,new,Redis,序列化,class,redisTemplate
From: https://www.cnblogs.com/ayizzz/p/17470019.html

相关文章

  • SpringMVC WebUploader 分片上传
    ​ 需求:项目要支持大文件上传功能,经过讨论,初步将文件上传大小控制在500G内,因此自己需要在项目中进行文件上传部分的调整和配置,自己将大小都以500G来进行限制。PC端全平台支持,要求支持Windows,Mac,Linux支持所有浏览器。支持文件批量上传支持文件夹上传,且要求在服务端保留层......
  • JDK 动态代理 和 CGLIB 动态代理 的区别【SpringAOP】
    一、原理区别(版本一)Java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。1、如果目标对象实现了接口,默认......
  • 构建高可用、高效、安全和可靠的分布式系统:Spring Cloud为开发人员提供便利
    SpringCloud是一个基于Spring框架的云应用开发工具箱,可以快速构建分布式应用程序。它为开发人员提供了许多有用的功能,例如服务发现、负载均衡、配置管理和应用监控等,这些功能可以使分布式系统更加稳定和可靠。如果您还没有了解过SpringCloud,我强烈建议您观看以下这个视频链接:ht......
  • gateway结合redis做限流
    本篇是针对已经实现了gateway基础功能的项目,如果需要实现基础功能可以参考https://www.cnblogs.com/cbzhl/p/17467019.html针对于并发量比较高的时候,如果不针对对应的服务做限流操作,可能造成服务器压力过大,宕机等情况,为此出现了多种限流的方式:计数器算法(Counter)。--设计一个......
  • 简单记录下Spring boot 3.1的升级过程
    SpringBoot在2023年的5月18号发布了3.1版本,手里有些项目版本是2.X,借这个机会把项目升级到最新版本+更新JDK20在这里简单随便记录一下踩坑的地方,在文章的末尾放上了官方的migration向导,你可以根据此参考升级你的项目。 通过SpringInitializr获取最新的版本,拷贝至项目里。 ......
  • java(springboot)实现将一个pdf按页码转成多张图片
    以下是一个将PDF转换成JPG格式图片的SpringBoot接口代码:importorg.apache.pdfbox.pdmodel.PDDocument;importorg.apache.pdfbox.rendering.PDFRenderer;importorg.springframework.http.MediaType;importorg.springframework.scheduling.annotation.Async;import......
  • Quartz + SpringBoot 实现定时任务(多任务,多执行时间)代码模板(直接CV即可)
    一,什么是Quartzquartz是一款开源且丰富特性的Java任务调度库,用于实现任务调度和定时任务。它支持各种任务类型和灵活的配置选项,具备作业持久化、集群和分布式调度、错误处理和重试机制等功能。Quartz被广泛应用于各种应用程序中,提供可靠和灵活的任务调度解决方案。二,核心概念......
  • [spring-boot] 源码解读#org.springframework.boot.ApplicationArguments [转发]
    1ApplicationArguments概述1.1简述org.springframework.boot.ApplicationArguments接口提供对用于运行org.springframework.boot.SpringApplication的参数访问。ApplicationArguments接口只有一个实现类DefaultApplicationArguments。1.2使用示例示例1@SpringBootA......
  • 用Spring MVC实现用户登录的完整实例
    用SpringMVC实现用户登录的完整实例本例子是再Eclipse中建立一个Tomcat工程,来讲解SpringMVC的全过程,实例代码如下:<一>编写日记文件放在myMVC/WEB-INF/src下#指定日志输入文件的大小log4j.appender.stdout.MaxFileSize=500KBlog4j.appender.stdout.MaxBackupI......
  • 使用Spring方法注入协调不同步的bean
    使用Spring方法注入协调不同步的bean<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd"><beans><bean......