常见的的序列化反序列方式的效率:

protoBuf(PB) > fastjson > jackson > hessian > xstream > java

数据来自于:https://github.com/eishay/jvm-serializers/wiki

所以我选择了java方式、jackson方式、fastjson方式、pb方式做了封装并测试,测试结果如下:

jackson、pb、fastjson差不太多,jackson稍好些,java方式非常慢不推荐,jackson是springboot自带的json序列化工具,所以推荐这种方式做redis对象存取。

下面是四种实现方式:

java自带序列化

序列化工具方法

  /**
* 序列化
*
* @param object
* @return
*/
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
// 序列化
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
} /**
* 反序列化
*
* @param bytes
* @return
*/
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
try {
// 反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}

redisUtils

  
  @Autowired
  private StringRedisTemplate redisTemplate;
  /**
* 以二进制序列化方式向redis保存对象 2019
*
* @param key
* @param value
*/
public void setObj(String key, Object value) {
final byte[] vbytes = SerializeUtil.serialize(value);
redisTemplate.execute(new RedisCallback() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
// connection.set(redisTemplateSer.getStringSerializer().serialize(key), vbytes);
connection.set(SerializeUtil.serialize(key), vbytes);
return null;
}
});
} /**
* 以二进制序列化方式从redis获取对象 2019
*
* @param key
* @param <T>
* @return
*/
public <T> T getObj(String key) {
return redisTemplate.execute(new RedisCallback<T>() {
@Override
public T doInRedis(RedisConnection connection) throws DataAccessException {
// byte[] keyByte = redisTemplateSer.getStringSerializer().serialize(key);
byte[] keyByte = SerializeUtil.serialize(key); if (connection.exists(keyByte)) {
byte[] valuebytes = connection.get(keyByte);
@SuppressWarnings("unchecked")
T value = (T) SerializeUtil.unserialize(valuebytes);
return value;
}
return null;
}
});
}

Jackson、fastjson

序列化工具方法

        /**
* jackson序列化反序列化工具
*/
private static ObjectMapper objectMapper = new ObjectMapper(); public static <T> String obj2String(T obj) {
if (obj == null) {
return null;
}
try {
return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} //字符串转对象
public static <T> T string2Obj(String str, Class<T> clazz) {
if (StringUtils.isEmpty(str) || clazz == null) {
return null;
}
try {
return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
} catch (IOException e) {
e.printStackTrace();
return null;
}
} // /**
// * fastjson序列化反序列化工具
// */
// public static <T> String obj2String(T obj) {
// return JSON.toJSONString(obj);
// }
//
// //字符串转对象
// public static <T> T string2Obj(String str, Class<T> clazz) {
// return JSON.parseObject(str,clazz);
// }

redisUtils

  /**
* 以JSON序列化方式向redis保存对象 推荐这种用法速度快 2019
* @param key
* @param value
*/
public void setObjJson(String key,Object value){
redisTemplate.opsForValue().set(key,SerializeUtil.obj2String(value));
} /**
* 以JSON序列化方式从redis获取对象 推荐这种用法速度快 2019
* @param key
* @param clazz
* @param <T>
* @return
*/
public <T> T getObjJson(String key,Class<T> clazz){
String strValue = redisTemplate.opsForValue().get(key);
if(!StringUtils.isEmpty(strValue)){
T value = SerializeUtil.string2Obj(strValue,clazz);
return value;
}
return null;
}

ProtoBuf方式

maven依赖

        <!-- protostuff -->
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.4.0</version>
</dependency>

序列化工具方法

    /**
* protobuf序列化工具
*/
public static <T> byte[] serializePb(T o) {
Schema schema = RuntimeSchema.getSchema(o.getClass());
return ProtobufIOUtil.toByteArray(o, schema, LinkedBuffer.allocate(256));
} public static <T> T unserializePb(byte[] bytes, Class<T> clazz) { T obj = null;
try {
obj = clazz.newInstance();
Schema schema = RuntimeSchema.getSchema(obj.getClass());
ProtostuffIOUtil.mergeFrom(bytes, obj, schema);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} return obj;
}

redisUtils,pb方式如果是嵌套对象会有一定问题(这块回头再研究一下),并且需要序列化的成员变量需要添加@Tag(7)注解,如:

@Data
public class SimplePojo {
@Tag(1)
private String a;
@Tag(2)
private String b;
@Tag(3)
private String c;
  /**
* 以pb序列化方式向redis保存对象 2019
*
* @param key
* @param value
*/
public void setObjPb(String key, Object value) {
final byte[] vbytes = SerializeUtil.serializePb(value);
redisTemplate.execute(new RedisCallback() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.set(SerializeUtil.serializePb(key), vbytes);
return null;
}
});
} /**
* 以pb序列化方式从redis获取对象 2019
*
* @param key
* @param <T>
* @return
*/
public <T> T getObjPb(String key,Class<T> clazz) {
return redisTemplate.execute(new RedisCallback<T>() {
@Override
public T doInRedis(RedisConnection connection) throws DataAccessException {
byte[] keyByte = SerializeUtil.serializePb(key); if (connection.exists(keyByte)) {
byte[] valuebytes = connection.get(keyByte);
@SuppressWarnings("unchecked")
T value = (T) SerializeUtil.unserializePb(valuebytes,clazz);
return value;
}
return null;
}
});
}

Fork From GIT

更详细的的源码详见:https://gitee.com/zxporz/redistest/blob/master/src/main/java/org/zxp/redis/utils/RedisUtil.java

欢迎fork

三种序列化方式存取redis的方法的更多相关文章

  1. 分布式锁的三种实现方式 数据库、redis、zookeeper

    版权声明: https://blog.csdn.net/wuzhiwei549/article/details/80692278 一.为什么要使用分布式锁 我们在开发应用的时候,如果需要对某一个共享变 ...

  2. 并发编程系列小结(线程安全,synchronized,脏读,线程间的通信wait/notify,线程的三种实现方式Demo,可替代wait/notify的方法)

    线程安全: 当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法就是线程安全的) synchronized: 可以在任意对象或方法上加锁,而加锁的这段代码称为 ...

  3. 大数据学习day13------第三阶段----scala01-----函数式编程。scala以及IDEA的安装,变量的定义,条件表达式,for循环(守卫模式,推导式,可变参数以及三种遍历方式),方法定义,数组以及集合(可变和非可变),数组中常用的方法

    具体见第三阶段scala-day01中的文档(scala编程基础---基础语法)  1. 函数式编程(https://www.cnblogs.com/wchukai/p/5651185.html): ...

  4. python笔记-20 django进阶 (model与form、modelform对比,三种ajax方式的对比,随机验证码,kindeditor)

    一.model深入 1.model的功能 1.1 创建数据库表 1.2 操作数据库表 1.3 数据库的增删改查操作 2.创建数据库表的单表操作 2.1 定义表对象 class xxx(models.M ...

  5. 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)

    摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...

  6. Storm 学习之路(六)—— Storm项目三种打包方式对比分析

    一.简介 在将Storm Topology提交到服务器集群运行时,需要先将项目进行打包.本文主要对比分析各种打包方式,并将打包过程中需要注意的事项进行说明.主要打包方式有以下三种: 第一种:不加任何插 ...

  7. Storm 系列(六)—— Storm 项目三种打包方式对比分析

    一.简介 在将 Storm Topology 提交到服务器集群运行时,需要先将项目进行打包.本文主要对比分析各种打包方式,并将打包过程中需要注意的事项进行说明.主要打包方式有以下三种: 第一种:不加任 ...

  8. Django-多对多关系的三种创建方式-forms组件使用-cookie与session-08

    目录 表模型类多对多关系的三种创建方式 django forms 组件 登录功能手写推理过程 整段代码可以放过来 forms 组件使用 forms 后端定义规则并校验结果 forms 前端渲染标签组件 ...

  9. 三种存储方式DAS、NAS、SAN

    ------------恢复内容开始------------ 一.DAS.NAS.SAN在存储领域的位置 随着主机.磁盘.网络等技术的发展,数据存储的方式和架构也在一直不停改变,本文主要介绍目前主流的 ...

随机推荐

  1. 1、gitlab的理论知识

    2.1 svn与git对比 . svn git 分布式 不是 是 在线阅读 不支持 不仅支持,而且可以在线编辑 存储方式 按文件 按元数据 完整性 一般 优 离线工作 日志都没法看 完全没问题 分支 ...

  2. Oracle插入中文数据乱码 设置服务器编码和客户端编码一致

  3. jmeter将参数值写入到指定文件(转)

    有时在测试过程中需要将测试过程中生成的参数保存下来,jmeter并没有此类功能,此时,可以 通过beanshell编写代码来实现 思路: 每次请求响应返回后,通过正则表达式获取到需要保存的值,通过Be ...

  4. js中的一些问题

    1.当有其他的库也是使用的是"$",则可以这样写jquery代码: var jQ = jQuery.noConflict(); //把jQuery中的$赋给jQ变量 (functi ...

  5. ES6扩展运算符...进行的数组删除

    今天写了按照React小书写了Reducer,发现基础真是太重要了,所有关于上层建筑的细节都需要回到下层细节中去寻找,而且现在的基础也由ES3变成了ES6了. const ADD_USER = &qu ...

  6. Ubuntu16.04双网卡绑定

    服务器经常有多个网卡,为了保证网络冗余性,一个网卡出现故障时,不导致网络服务中断,可以懂多网卡网卡绑定来解决此问题. 环境: 系统:Ubuntu16.04 网卡:em1 em2 ip:192.168. ...

  7. 多级联动的select框

    JS文件: ; (function($, w) { var LinkSelect = function(config) { var opt = { doms: config.doms || [], u ...

  8. 使用open live writer客户端写博客(亲测有效)

    博客都开了这么久了,才开始将资料上传,但是每次都要登录网页确实很麻烦,所以就用open live writer,使用起来真的是挺方便的,所以将我在安装配置时,发现的问题汇总起来以便日后再次碰到忘记怎么 ...

  9. pat1049. Counting Ones (30)

    1049. Counting Ones (30) 时间限制 10 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The task ...

  10. spring boot注入error,Consider defining a bean of type 'xxx' in your configuration问题解决方案

    经常出现这问题一定是非spring生态圈的@标签 没被spring引入,如mybatis等 因为在默认情况下只能扫描与控制器在同一个包下以及其子包下的@Component注解,以及能将指定注解的类自动 ...