spring redistemplate中setHashValueSerializer的设置
笔者曾经对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 redistemplate中setHashValueSerializer的设置的更多相关文章
- Spring Boot中使用redis的发布/订阅模式
原文:https://www.cnblogs.com/meetzy/p/7986956.html redis不仅是一个非常强大的非关系型数据库,它同时还拥有消息中间件的pub/sub功能,在sprin ...
- Spring Cloud中Feign如何统一设置验证token
代码地址:https://github.com/hbbliyong/springcloud.git 原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过 ...
- Spring Boot中使用Redis小结
Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, 等. Redis简单介绍 Redi ...
- Spring Boot中使用缓存
Spring Boot中使用缓存 随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一. 原始的使 ...
- Spring Boot 中 Redis 的使用
Spring Boot 对常用的数据库支持外,对 Nosql 数据库也进行了封装自动化,如Redis.MongoDB等,本文主要介绍Redis的使用. Redis 介绍 Redis 是目前业界使用最广 ...
- 【主流技术】Redis 在 Spring 框架中的实践
前言 在Java Spring 项目中,数据与远程数据库的频繁交互对服务器的内存消耗比较大,而 Redis 的特性可以有效解决这样的问题. Redis 的几个特性: Redis 以内存作为数据存储介质 ...
- spring boot(三):Spring Boot中Redis的使用
spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...
- springboot(三):Spring boot中Redis的使用
spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...
- Spring Boot:Spring Boot 中 Redis 的使用
Redis 介绍 Redis 是目前业界使用最广泛的内存数据存储.相比 Memcached,Redis 支持更丰富的数据结构,例如 hashes, lists, sets 等,同时支持数据持久化.除此 ...
随机推荐
- 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 ...
- 多任务创建-线程(IO密集型适用)
单核CPU:时间片轮转 并行:CPU的个数大于等于任务数 真的多任务执行 并发:CPU的个数小于任务数 假的多任务 知识点: 多线程共享全局变量 创建线程的两种方法: 1.创建子线程方法 调用函数 T ...
- 05_Tutorial 5: Relationships & Hyperlinked APIs 关系和超链接
1.关系和超链接 0.文档 https://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/ h ...
- Python-sokect 示例
server: #coding=utf-8 import socket _sokect =socket.socket() #创建sokect _host =socket.gethostname() # ...
- VIM--保存和退出等命令
在 Linux 中使用 vim 时,输入 vim xxx.file 按 ESC,左下角就可以进行输入 :w 保存但不退出 :wq 保存并退出 :q 退出 :q! 强制退出,不保存 :e! 放弃所有修改 ...
- 013——C# chart控件时间作为X轴(附教程)
(一)参考文献:C#之Chart控件系列教程——一 (二)下载地址:https://download.csdn.net/download/xiaoguoge11/11838944 (三)视频教程:ht ...
- (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作
二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...
- Python3数字
Python3数字数据类型用于存储数值. 数据类型是不允许改变的,这就意味着,如果改变数字数据类型的值,将重新分配内存空间. Python支持三种不同不同的数值类型: 整型(int):通常是被称为整型 ...
- 1.OC类
一.基础语法 1.在OC中,一般用2个文件来描述一个类: 1> .h:类的声明文件,用于声明成员变量.方法.类的声明使用关键字@interface和@end. 注意:.h中的方法只是做一个声明, ...
- 解决Ubuntu重启后,core_pattern失效问题——手动关闭apport
云主机重启后,core_pattern,即/proc/sys/kernel/core_pattern和/etc/sysctl*配置失效,被系统自动修改. 配置后,重启后core_pattern被重写 ...