当前位置:网站首页>Redis 序列化 GenericJackson2JsonRedisSerializer和Jackson2JsonRedisSerializer的区别
Redis 序列化 GenericJackson2JsonRedisSerializer和Jackson2JsonRedisSerializer的区别
2022-07-02 06:33:00 【保护我方胖虎】
文章目录
/** * 实例化 RedisTemplate 对象 * @return */
@Bean
public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key 都使用String 序列化方式
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
GenericJackson2JsonRedisSerializer
GenericJackson2JsonRedisSerializer序列化时,会保存序列化的对象的完全限定名,从redis获取数据时即可直接反序列化成指定的对象
通用参数如下:
List<Student> students = new ArrayList<>();
Student xm = new Student("小明", 12);
Student ph = new Student("胖虎", 12);
students.add(xm);
students.add(ph);
(1)VALUE 存普通对象
存:
Student xm = new Student("小明", 12);
redisTemplate.opsForValue().set(xm.getName(), xm);
值中附带了实体信息
取:
Student xmCache = (Student)redisTemplate.opsForValue().get(xm.getName());
// Student(name=小明, age=12)
System.out.println(xmCache);
结论:GenericJackson2JsonRedisSerializer 序列化方式 可直接存储VALUE为对象,且从Redis获取可进行强转
(2)VALUE 存对象集合
存:
redisTemplate.opsForSet().add("students-genericJackson2JsonRedisSerializer", students);
redisTemplate.opsForValue().set("students-str", students);
值中既有实体类完全限定名又有集合类型
–
具体值中携带了实体类完全限定名
取:
List<Student> studentCache = (List<Student>) redisTemplate.opsForValue().get("students-str");
Set<Object> members = redisTemplate.opsForSet().members("students-genericJackson2JsonRedisSerializer");
// [Student(name=小明, age=12), Student(name=胖虎, age=12)]
System.out.println(studentCache);
// [Student(name=胖虎, age=12), Student(name=小明, age=12)]
System.out.println(members);
结论:GenericJackson2JsonRedisSerializer 序列化方式 可直接存储VALUE为对象集合,且从Redis获取可进行强转
(3)VALUE 存JSON字符串
redisTemplate.opsForValue().set(ph.getName(), JSON.toJSONString(ph));
存:
无@class字段,且jSON字符串中含有转义符
取:
Object o = redisTemplate.opsForValue().get(ph.getName());
System.out.println(o);
注意点:因为这里存是JSON字符串,所以取数据时候,也无法直接强制转为Student对象,我们需要手动调用方法,将JSON字符串转换为JAVA对象
redisTemplate.opsForValue().set(ph.getName(), JSON.toJSONString(ph));
Object o = redisTemplate.opsForValue().get(ph.getName());
// Student(name=胖虎, age=12)
System.out.println(o == null ? null : JSON.parseObject(o.toString(), Student.class));
结论:GenericJackson2JsonRedisSerializer 序列化方式 可直接存储VALUE为JSON字符串形式,且从Redis获取后不可进行强转,需要将结果转为字符串,再将JSON字符串转为自己需要的对象或对象集合
(4)管道Pipelined存数据
存:
List<Student> students = new ArrayList<>();
Student xm = new Student("小明", 12); Student ph = new Student("胖虎", 12);
students.add(xm); students.add(ph);
redisTemplate.executePipelined((RedisCallback) conn -> {
students.forEach(s -> conn.set(s.getName().getBytes(), JSON.toJSONString(s).getBytes()));
return null;
});
管道操作的数据并没有@class 实体类属性,实体类完全限定名丢失,那么这个时候还能否获取数据呢?
答案是不能
取:
取完直接强转:
Student xmCache = (Student)redisTemplate.opsForValue().get(xm.getName());
System.out.println(xmCache);
GET取完不强转
Object xmCache = redisTemplate.opsForValue().get(xm.getName());
System.out.println(xmCache);
MGET 批量获取
List<Object> objectList = redisTemplate.opsForValue().multiGet(students.stream().map(Student::getName).collect(Collectors.toList()));
System.out.println(objectList);
return objectList;
ERROR 16400 — [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property ‘@class’
at [Source: (byte[])"{“age”:12,“name”:“小明”}"; line: 1, column: 26]; nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property ‘@class’
at [Source: (byte[])"{“age”:12,“name”:“小明”}"; line: 1, column: 26]] with root cause
翻译过来的意思是:无法读取 JSON:尝试解析 [简单类型,类 java.lang.Object] 的子类型时缺少类型 ID:缺少类型 id 属性“@class”
结论: 使用GenericJackson2JsonRedisSerializer 序列化进行管道操作后,实体类@class属性会丢失,再次从redis获取数据将无法成功反序列化
Jackson2JsonRedisSerializer
通用参数如下:
List<Student> students = new ArrayList<>();
Student ys = new Student("亚索", 12);
Student mw = new Student("蛮王", 12);
students.add(ys);
students.add(mw);
(1)VALUE 存普通对象
存:
redisTemplate.opsForValue().set(ys.getName(), ys);
redisTemplate.opsForValue().set(mw.getName(), mw);
取:
Student ysCache = (Student)redisTemplate.opsForValue().get(ys.getName());
System.out.println(ysCache);
发现报错:java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.leilei.entity.Student
断点调试:获取的ysCache 实际是一个LinkedHashMap
Object ysCache = redisTemplate.opsForValue().get(ys.getName());
System.out.println(ysCache);
存对象集合结果一样…
redisTemplate.opsForValue().set("lol", students);
Object lolCache = redisTemplate.opsForValue().get("lol");
System.out.println(lolCache);
解决办法:
Jackson2JsonRedisSerializer序列化时 存数据都采用JSON字符串方式,然后取数据时也不直接将结果强转,而是使用JSON反序列化 将JSON字符串反序列化为java对象或集合
请看示例二:VALUE 存JSON字符串
结论:Jackson2JsonRedisSerializer序列化方式,如VALUE直接存对象或者对象集合,获取时结果为LinkedHashMap,无法直接使用JDK强转方法转为对象或对象集合,需借助工具进行转换为实体与实体集合
(2)VALUE 存JSON字符串
存:
redisTemplate.opsForValue().set(ys.getName(), JSON.toJSONString(ys));
redisTemplate.opsForValue().set(mw.getName(), JSON.toJSONString(mw));
–
字符串中有转义字符
取:
Object ysCache = redisTemplate.opsForValue().get(ys.getName());
// Student(name=亚索, age=122)
System.out.println(ysCache == null ? null : JSON.parseObject(ysCache.toString(), Student.class));
List<Object> cacheList = redisTemplate.opsForValue().multiGet(students.stream().map(Student::getName).collect(Collectors.toList()));
List<Student> studentList = cacheList.stream().filter(Objects::nonNull).map(Object::toString).map(x -> JSON.parseObject(x, Student.class)).collect(Collectors.toList());
// [Student(name=亚索, age=122), Student(name=蛮王, age=234)]
System.out.println(studentList);
结论:Jackson2JsonRedisSerializer序列化方式,VALUE存JSON字符串时,取值也为JSON字符串,需借助JSON工具进行转换为实体类或实体集合
(3)管道Pipelined存数据
存:
redisTemplate.executePipelined((RedisCallback<String>) conn -> {
students.forEach(s -> conn.set(s.getName().getBytes(), JSON.toJSONString(s).getBytes()));
return null;
});
–
取:
获取管道存储的值变为了LinkedHashMap
因为我们需要将map转为java对象,我这里采用的是先转JSON字符串方式
List<Object> cacheList = redisTemplate.opsForValue().multiGet(students.stream().map(Student::getName).collect(Collectors.toList()));
if (CollectionUtils.isEmpty(cacheList)) {
return null;
}
List<Student> studentList = cacheList.stream().filter(Objects::nonNull).map(JSON::toJSONString).map(x -> JSON.parseObject(x, Student.class)).collect(Collectors.toList());
// [Student(name=亚索, age=122), Student(name=蛮王, age=234)]
System.out.println(studentList);
结论:Jackson2JsonRedisSerializer 序列化方式,且使用管道操作后,获取的值也是一个linkedHashMap,需借助工具才可将值反序列化为实体对象或实体对象集合
边栏推荐
- Matplotlib剑客行——布局指南与多图实现(更新)
- Mirror protocol of synthetic asset track
- 【Go实战基础】gin 如何绑定与使用 url 参数
- 远程连接IBM MQ报错AMQ4036解决方法
- Solutions to Chinese garbled code in CMD window
- "Redis source code series" learning and thinking about source code reading
- 一篇详解带你再次重现《统计学习方法》——第二章、感知机模型
- What is the future value of fluorite mine of karaqin Xinbao Mining Co., Ltd. under zhongang mining?
- Webflux responsive programming
- Knife4j 2.X版本文件上传无选择文件控件问题解决
猜你喜欢
Don't look for it. All the necessary plug-ins for Chrome browser are here
Flink-使用流批一体API统计单词数量
查看was发布的应用程序的端口
DTM distributed transaction manager PHP collaboration client V0.1 beta release!!!
Complete solution of servlet: inheritance relationship, life cycle, container, request forwarding and redirection, etc
队列管理器running状态下无法查看通道
View the port of the application published by was
[go practical basis] how to set the route in gin
Microservice practice | teach you to develop load balancing components hand in hand
Servlet全解:继承关系、生命周期、容器和请求转发与重定向等
随机推荐
ORA-12514问题解决方法
微服务实战|熔断器Hystrix初体验
Pyspark de duplication dropduplicates, distinct; withColumn、lit、col; unionByName、groupBy
Chrome视频下载插件–Video Downloader for Chrome
微服务实战|声明式服务调用OpenFeign实践
Essay: RGB image color separation (with code)
机器学习之数据类型案例——基于朴素贝叶斯法,用数据辩男女
Sentinel reports failed to fetch metric connection timeout and connection rejection
Knife4j 2.X版本文件上传无选择文件控件问题解决
Matplotlib swordsman Tour - an artist tutorial to accommodate all rivers
双非本科生进大厂,而我还在底层默默地爬树(上)
The channel cannot be viewed when the queue manager is running
oracle删除表空间及用户
[go practical basis] how to set the route in gin
Ora-12514 problem solving method
C Baidu map, Gaode map, Google map (GPS) longitude and latitude conversion
数构(C语言)——第四章、矩阵的压缩存储(下)
Watermelon book -- Chapter 5 neural network
Number structure (C language -- code with comments) -- Chapter 2, linear table (updated version)
Dix ans d'expérience dans le développement de programmeurs vous disent quelles compétences de base vous manquez encore?