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;
    
    }
    
学习使我充实,分享给我快乐!
原文地址:https://www.cnblogs.com/JaxYoun/p/14456996.html