- GenericJackson2JsonRedisSerializer
- (1)VALUE 存普通对象
- (2)VALUE 存对象集合
- (3)VALUE 存JSON字符串
- (4)管道Pipelined存数据
- Jackson2JsonRedisSerializer
- (1)VALUE 存普通对象
- (2)VALUE 存JSON字符串
- (3)管道Pipelined存数据
@Bean public RedisTemplateGenericJackson2JsonRedisSerializerfunctionDomainRedisTemplate(RedisConnectionFactory factory) { RedisTemplate redisTemplate = new RedisTemplate<>(); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key 都使用String 序列化方式 redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); // Jackson2JsonRedisSerializer
GenericJackson2JsonRedisSerializer序列化时,会保存序列化的对象的完全限定名,从redis获取数据时即可直接反序列化成指定的对象
通用参数如下:
List(1)VALUE 存普通对象students = new ArrayList<>(); Student xm = new Student("小明", 12); Student ph = new Student("胖虎", 12); students.add(xm); students.add(ph);
存:
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);
值中既有实体类完全限定名又有集合类型
–
具体值中携带了实体类完全限定名
取:
ListstudentCache = (List ) redisTemplate.opsForValue().get("students-str"); Set
结论: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存数据存:
Liststudents = 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
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(1)VALUE 存普通对象students = new ArrayList<>(); Student ys = new Student("亚索", 12); Student mw = new Student("蛮王", 12); students.add(ys); students.add(mw);
存:
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
结论:Jackson2JsonRedisSerializer序列化方式,VALUE存JSON字符串时,取值也为JSON字符串,需借助JSON工具进行转换为实体类或实体集合
(3)管道Pipelined存数据存:
redisTemplate.executePipelined((RedisCallback) conn -> { students.forEach(s -> conn.set(s.getName().getBytes(), JSON.toJSONString(s).getBytes())); return null; });
–
取:
获取管道存储的值变为了linkedHashMap
因为我们需要将map转为java对象,我这里采用的是先转JSON字符串方式
List
结论:Jackson2JsonRedisSerializer 序列化方式,且使用管道 *** 作后,获取的值也是一个linkedHashMap,需借助工具才可将值反序列化为实体对象或实体对象集合
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)