笔者曾经对redis键值使用了不同类型的序列化方法

用过默认值、JdkSerializationRedisSerializer、StringRedisSerializer还用改以下自定类型的序列化工具类(据说这个比Spring RedisTemplate的序列化、反序列化快)

import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException; public class ProtostuffSerializer implements RedisSerializer<Object> { private boolean isEmpty(byte[] data) {
return (data == null || data.length == 0);
} private final Schema<ProtoWrapper> schema; private final ProtoWrapper wrapper; private final LinkedBuffer buffer; public ProtostuffSerializer() {
this.wrapper = new ProtoWrapper();
this.schema = RuntimeSchema.getSchema(ProtoWrapper.class);
this.buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
} @Override
public byte[] serialize(Object t) throws SerializationException {
if (t == null) {
return new byte[0];
}
wrapper.data = t;
try {
return ProtostuffIOUtil.toByteArray(wrapper, schema, buffer);
} finally {
buffer.clear();
}
} @Override
public Object deserialize(byte[] bytes) throws SerializationException {
if (isEmpty(bytes)) {
return null;
} ProtoWrapper newMessage = schema.newMessage();
ProtostuffIOUtil.mergeFrom(bytes, newMessage, schema);
return newMessage.data;
} private static class ProtoWrapper { public Object data; }
}

遇到过以下异常:

hash操作:java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String,然后这次又换另外一个Hash的序列化类

template.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));

序列化后的缓存如下:

因为上次使用ProtostuffSerializer对Hash值进行序列化,进行以下操作报错了

HashOperations<String,String,T> hashOperations = redisTemplate.opsForHash();

        if(value instanceof Long || value instanceof Integer|| value instanceof Short||value instanceof Byte)
{
long longValue = ((Number) value).longValue();
hashOperations.increment(key,field,longValue);
} if(value instanceof Float ||value instanceof Double)
{
double doubleValue = ((Number) value).doubleValue();
Double returned = hashOperations.increment(key, field, -0.005);
}
return hashOperations;

报错如下:io.lettuce.core.RedisCommandExecutionException: ERR hash value is not a valid float

,因为经过ProtostuffSerializer序列化的hash值会变形,编程、\X0A=\X5A\X43\XC格式的数据,进行数值运算报错。

注意事项:redis端increment操作,只支持double和long,所以数据要进行相关转换。

比如笔者代码如下,就会报错:

 public <T> T getCacheHashValue(String key, String field, Class<T> targetClass) {
HashOperations<String,String,T> hashOperations = redisTemplate.opsForHash();
return hashOperations.get(key, field);
}

传入

Float balance = cacheService.getCacheHashValue(cacheKey, "balance", Float.class);

报错:

Caused by: java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Float

redisTemplate相关文章:

springboot项目中使用spring-data-Redis对map序列化时报错

使用redisTemplate存储数据,出现\xAC\xED\x00\x05t\x00

参考:

Spring-data-redis @Cacheable java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String

spring redistemplate中setHashValueSerializer的设置的更多相关文章

  1. Spring Boot中使用redis的发布/订阅模式

    原文:https://www.cnblogs.com/meetzy/p/7986956.html redis不仅是一个非常强大的非关系型数据库,它同时还拥有消息中间件的pub/sub功能,在sprin ...

  2. Spring Cloud中Feign如何统一设置验证token

    代码地址:https://github.com/hbbliyong/springcloud.git 原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过 ...

  3. Spring Boot中使用Redis小结

    Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, 等. Redis简单介绍 Redi ...

  4. Spring Boot中使用缓存

    Spring Boot中使用缓存 随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一. 原始的使 ...

  5. Spring Boot 中 Redis 的使用

    Spring Boot 对常用的数据库支持外,对 Nosql 数据库也进行了封装自动化,如Redis.MongoDB等,本文主要介绍Redis的使用. Redis 介绍 Redis 是目前业界使用最广 ...

  6. 【主流技术】Redis 在 Spring 框架中的实践

    前言 在Java Spring 项目中,数据与远程数据库的频繁交互对服务器的内存消耗比较大,而 Redis 的特性可以有效解决这样的问题. Redis 的几个特性: Redis 以内存作为数据存储介质 ...

  7. spring boot(三):Spring Boot中Redis的使用

    spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...

  8. springboot(三):Spring boot中Redis的使用

    spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...

  9. Spring Boot:Spring Boot 中 Redis 的使用

    Redis 介绍 Redis 是目前业界使用最广泛的内存数据存储.相比 Memcached,Redis 支持更丰富的数据结构,例如 hashes, lists, sets 等,同时支持数据持久化.除此 ...

随机推荐

  1. How to parse unix timestamp to time.Time

      The time.Parse function does not do Unix timestamps. Instead you can use strconv.ParseInt to parse ...

  2. 多任务创建-线程(IO密集型适用)

    单核CPU:时间片轮转 并行:CPU的个数大于等于任务数 真的多任务执行 并发:CPU的个数小于任务数 假的多任务 知识点: 多线程共享全局变量 创建线程的两种方法: 1.创建子线程方法 调用函数 T ...

  3. 05_Tutorial 5: Relationships & Hyperlinked APIs 关系和超链接

    1.关系和超链接 0.文档 https://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/ h ...

  4. Python-sokect 示例

    server: #coding=utf-8 import socket _sokect =socket.socket() #创建sokect _host =socket.gethostname() # ...

  5. VIM--保存和退出等命令

    在 Linux 中使用 vim 时,输入 vim xxx.file 按 ESC,左下角就可以进行输入 :w 保存但不退出 :wq 保存并退出 :q 退出 :q! 强制退出,不保存 :e! 放弃所有修改 ...

  6. 013——C# chart控件时间作为X轴(附教程)

    (一)参考文献:C#之Chart控件系列教程——一 (二)下载地址:https://download.csdn.net/download/xiaoguoge11/11838944 (三)视频教程:ht ...

  7. (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作

    二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...

  8. Python3数字

    Python3数字数据类型用于存储数值. 数据类型是不允许改变的,这就意味着,如果改变数字数据类型的值,将重新分配内存空间. Python支持三种不同不同的数值类型: 整型(int):通常是被称为整型 ...

  9. 1.OC类

    一.基础语法 1.在OC中,一般用2个文件来描述一个类: 1> .h:类的声明文件,用于声明成员变量.方法.类的声明使用关键字@interface和@end. 注意:.h中的方法只是做一个声明, ...

  10. 解决Ubuntu重启后,core_pattern失效问题——手动关闭apport

    云主机重启后,core_pattern,即/proc/sys/kernel/core_pattern和/etc/sysctl*配置失效,被系统自动修改. 配置后,重启后core_pattern被重写 ...