SpringBoot基于SpringDataRedis配置RedisTemplate
SpringBoot基于SpringDataRedis配置RedisTemplate
-
JdkSerializationRedisSerializer,所有参与序列化的类必须实现
Serializable标记接口-
普通对象 + 普通泛型(支持)
-
普通对象 + LocalDateTime泛型(支持)
优点:它是SpringDataRedis的RedisTemplate默认序列化器,针对各种类型都能方便地实现序列化和反序列化,泛型支持完整。
缺点:速度较慢,压缩率较低,可读性差。
# 这是JDK序列化一个hash结构后的二进制结果 key = \xac\xed\x00\x05t\x00\x0d1614414476908 hashKey = \xac\xed\x00\x05t\x00\x11hkey1614414476908 hashValue = \xac\xed\x00\x05sr\x00'com.yang.springdataredisopt.entity.User\xb5\x86z\xf8\xc7\xde~\\x02\x00\x03L\x00\x02idt\x00\x13Ljava/lang/Integer;L\x00\x04namet\x00\x12Ljava/lang/String;L\x00\x08timeListt\x00\x10Ljava/util/List;xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01t\x00\x04yangsr\x00\x13java.util.ArrayListx\x81\xd2\x1d\x99\xc7a\x9d\x03\x00\x01I\x00\x04sizexp\x00\x00\x00\x02w\x04\x00\x00\x00\x02sr\x00\x0djava.time.Ser\x95]\x84\xba\x1b"H\xb2\x0c\x00\x00xpw\x0e\x05\x00\x00\x07\xe5\x02\x1b\x10\x1b86\x1e\xfb\x00xsq\x00~\x00\x0bw\x0e\x05\x00\x00\x07\xe5\x02\x1b\x10\x1b86\x1e\xfb\x00xx
-
-
Jackson2JsonRedisSerializer
-
普通对象 + 普通泛型:序列化成功,需加ObjectMapper,否则反序列化失败。若加ObjectMapper,则JSON串中会包含类型信息。
-
普通对象 + LocalDateTime泛型:序列化成功,加了ObjectMapper,仍然反序列化失败。若加ObjectMapper,则JSON串中会包含类型信息。
优点:效率高,可读性好。
缺点:泛型支持不完整。
-
-
GenericJackson2JsonRedisSerializer【推荐使用】
-
普通对象 + 普通泛型:序列化、反序列化均成功,即使不加ObjectMapper,JSON串中也包含类型信息。
-
普通对象 + LocalDateTime泛型:序列化成功,需加ObjectMapper,否则反序列化失败。
优点:可读性高,泛型支持完整。
缺点:效率稍低。
-
-
还有一种实现就是直接使用StringRedisTemplate,SpringDataRedis提供了现成的实现,key和value的序列化器都是StringRedisSerializer。写入Redis时,手动将value对象序列化为JSON串后存入Redis;读取时直接读出JSON串,再手动反序列化为value对象。
-
配置及示例
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; }
学习使我充实,分享给我快乐!

浙公网安备 33010602011771号