zoukankan      html  css  js  c++  java
  • SpringBoot基于SpringDataRedis配置RedisTemplate

    SpringBoot基于SpringDataRedis配置RedisTemplate

    1. JdkSerializationRedisSerializer,所有参与序列化的类必须实现Serializable标记接口

      • 普通对象 + 普通泛型(支持)

      • 普通对象 + LocalDateTime泛型(支持)

        优点:它是SpringDataRedis的RedisTemplate默认序列化器,针对各种类型都能方便地实现序列化和反序列化,泛型支持完整

        缺点:速度较慢,压缩率较低,可读性差。

        # 这是JDK序列化一个hash结构后的二进制结果
        
        key = xacxedx00x05tx00x0d1614414476908
        
        hashKey = xacxedx00x05tx00x11hkey1614414476908
        
        hashValue =
        xacxedx00x05srx00'com.yang.springdataredisopt.entity.Userxb5x86zxf8xc7xde~\x02x00x03Lx00x02idtx00x13Ljava/lang/Integer;Lx00x04nametx00x12Ljava/lang/String;Lx00x08timeListtx00x10Ljava/util/List;xpsrx00x11java.lang.Integerx12xe2xa0xa4xf7x81x878x02x00x01Ix00x05valuexrx00x10java.lang.Numberx86xacx95x1dx0bx94xe0x8bx02x00x00xpx00x00x00x01tx00x04yangsrx00x13java.util.ArrayListxx81xd2x1dx99xc7ax9dx03x00x01Ix00x04sizexpx00x00x00x02wx04x00x00x00x02srx00x0djava.time.Serx95]x84xbax1b"Hxb2x0cx00x00xpwx0ex05x00x00x07xe5x02x1bx10x1b86x1exfbx00xsqx00~x00x0bwx0ex05x00x00x07xe5x02x1bx10x1b86x1exfbx00xx
        
    2. Jackson2JsonRedisSerializer

      • 普通对象 + 普通泛型:序列化成功,需加ObjectMapper,否则反序列化失败。若加ObjectMapper,则JSON串中会包含类型信息。

      • 普通对象 + LocalDateTime泛型:序列化成功,加了ObjectMapper,仍然反序列化失败。若加ObjectMapper,则JSON串中会包含类型信息。

        优点:效率高,可读性好。

        缺点:泛型支持不完整

    3. GenericJackson2JsonRedisSerializer【推荐使用】

      • 普通对象 + 普通泛型:序列化、反序列化均成功,即使不加ObjectMapper,JSON串中也包含类型信息

      • 普通对象 + LocalDateTime泛型:序列化成功,需加ObjectMapper,否则反序列化失败。

        优点:可读性高,泛型支持完整

        缺点:效率稍低。

    4. 还有一种实现就是直接使用StringRedisTemplate,SpringDataRedis提供了现成的实现,key和value的序列化器都是StringRedisSerializer。写入Redis时,手动将value对象序列化为JSON串后存入Redis;读取时直接读出JSON串,再手动反序列化为value对象。

    5. 配置及示例

      package com.yang.springdataredisopt.config;
      
      import com.fasterxml.jackson.annotation.JsonAutoDetect;
      import com.fasterxml.jackson.annotation.JsonTypeInfo;
      import com.fasterxml.jackson.annotation.PropertyAccessor;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import com.fasterxml.jackson.databind.SerializationFeature;
      import com.fasterxml.jackson.databind.module.SimpleModule;
      import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
      import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.data.redis.connection.RedisConnectionFactory;
      import org.springframework.data.redis.core.RedisTemplate;
      import org.springframework.data.redis.core.StringRedisTemplate;
      import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
      import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
      import org.springframework.data.redis.serializer.RedisSerializer;
      import org.springframework.data.redis.serializer.StringRedisSerializer;
      
      import java.net.UnknownHostException;
      
      /**
       * @author: Yang
       * @date: 2018/10/16 22:11
       * @description: 只配置了用于Redis服务端交互的模板配置
       */
      @Configuration
      public class RedisConfig {
      
          /**
           * 这是一个比较标准的Redis模板配置样例
           *
           * @param redisConnectionFactory
           * @return
           */
          @Bean
          public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
              //1.实例化序列化组件,此处用jackson
              Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
      
              //【注意:在一个项目中的多重模板应该尽量保持key和hkey的序列化组件一致,
              // 这样才能保证不同模板对key的操作是一致的,不会出现一种模板放的key另外一种模板拿不到的问题】
              RedisSerializer<String> stringSerializer = new StringRedisSerializer();
      
              //2.实例化Jackson的json映射器并配属性
              ObjectMapper om = new ObjectMapper();
              om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
              om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
      
              //3.将json映射器配置给序列化组件
              jackson2JsonRedisSerializer.setObjectMapper(om);
      
              //4.实例化Redis模板,并为之配置连接工厂
              RedisTemplate<String, Object> template = new RedisTemplate<>();
              template.setConnectionFactory(redisConnectionFactory);
      
              //5.给模板配置序列化组建
              template.setKeySerializer(stringSerializer);
              template.setHashKeySerializer(stringSerializer);
              template.setValueSerializer(jackson2JsonRedisSerializer);
              template.setHashValueSerializer(jackson2JsonRedisSerializer);
              template.afterPropertiesSet();
              return template;
          }
      
          /**
           * 泛型支持良好的序列化器【推荐使用】
           *
           * @param redisTemplate
           * @return
           */
          @Bean
          public RedisTemplate<String, Object> genericRedisTemplate(RedisTemplate redisTemplate) {
              RedisSerializer stringSerializer = new StringRedisSerializer();
              redisTemplate.setKeySerializer(stringSerializer);
              redisTemplate.setHashKeySerializer(stringSerializer);
      
              ObjectMapper objectMapper = new ObjectMapper();
              objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
              objectMapper.registerModule(new JavaTimeModule());
              objectMapper.registerModule((new SimpleModule()));
              objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
      
              GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper);
              redisTemplate.setValueSerializer(serializer);
              redisTemplate.setHashValueSerializer(serializer);
              return redisTemplate;
          }
      
          /**
           * String类型模板实例化处,这里使用Spring-data-redis内置提供的模板类
           *
           * @param redisConnectionFactory
           * @return
           * @throws UnknownHostException
           */
          @Bean
          @ConditionalOnMissingBean
          public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
              return new StringRedisTemplate(redisConnectionFactory);
          }
      
      }
      
      package com.yang.springdataredisopt.rest;
      
      import com.yang.springdataredisopt.entity.Student;
      import com.yang.springdataredisopt.entity.User;
      import org.springframework.data.redis.core.RedisTemplate;
      import org.springframework.data.redis.core.StringRedisTemplate;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      import javax.annotation.Resource;
      import java.time.LocalDateTime;
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * @author: Yang
       * @date: 2021/2/27 14:25
       * @description:
       */
      @RestController
      @RequestMapping("/serializer")
      public class SerializerController {
      
          @Resource
          private RedisTemplate<String, Object> genericRedisTemplate;
      
          @Resource
          private StringRedisTemplate stringRedisTemplate;
      
          @GetMapping("/get")
          public Object get() {
              List<LocalDateTime> kk = new ArrayList<>(2);
              kk.add(LocalDateTime.now());
              kk.add(LocalDateTime.now());
      
              User user = User.builder().id(1).name("yang").timeList(kk).build();
              String key = String.valueOf(System.currentTimeMillis());
              String hkey = String.valueOf("hkey" + System.currentTimeMillis());
      
              genericRedisTemplate.opsForHash().put(key, hkey, user);
              User obj = (User) genericRedisTemplate.opsForHash().get(key, hkey);
              return obj;
          }
      
          @GetMapping("/get0")
          public Object get0() {
              List<Student> kk = new ArrayList<>(2);
              kk.add(new Student());
              kk.add(new Student());
      
              User user = User.builder().id(1).name("yang").studentList(kk).build();
              String key = String.valueOf(System.currentTimeMillis());
              String hkey = String.valueOf("hkey" + System.currentTimeMillis());
      
              genericRedisTemplate.opsForHash().put(key, hkey, user);
              User obj = (User) genericRedisTemplate.opsForHash().get(key, hkey);
              return obj;
          }
      
          @GetMapping("/init")
          public void init() {
      
          }
      }
      
      package com.yang.springdataredisopt.entity;
      
      import lombok.Builder;
      import lombok.Data;
      import java.io.Serializable;
      import java.time.LocalDateTime;
      import java.util.List;
      
      /**
       * @author: Yang
       * @date: 2018/10/21 23:56
       * @description:
       */
      @Data
      @Builder
      public class User implements Serializable {
      
          private Integer id;
      
          private String name;
      
          private List<Student> studentList;
      
          private List<LocalDateTime> timeList;
      
      }
      
      package com.yang.springdataredisopt.entity;
      
      import lombok.Data;
      import lombok.NoArgsConstructor;
      import java.io.Serializable;
      
      /**
       * @author: Yang
       * @date: 2018/10/22 01:37
       * @description:
       */
      @Data
      @NoArgsConstructor
      public class Student implements Serializable {
      
          private String clazz;
      
          private String teacher;
      
      }
      
    学习使我充实,分享给我快乐!
  • 相关阅读:
    现代软件工程 第一章 概论 第3题——韩婧
    现代软件工程 第一章 概论 第2题——韩婧
    小组成员邓琨、白文俊、张星星、韩婧
    UVa 10892 LCM的个数 (GCD和LCM 质因数分解)
    UVa 10780 幂和阶乘 求n!中某个因子的个数
    UVa 11859 除法游戏(Nim游戏,质因子)
    Codeforces 703C Chris and Road 二分、思考
    Codeforces 703D Mishka and Interesting sum 树状数组
    hdu 5795 A Simple Nim SG函数(多校)
    hdu 5793 A Boring Question 推公式(多校)
  • 原文地址:https://www.cnblogs.com/JaxYoun/p/14456996.html
Copyright © 2011-2022 走看看