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

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. myclipse运行web的一些问题

    一.修改项目访问路径 项目右键>properties(属性)>输入web搜索>双击web>修改Web-Content root内容即可 二. myeclipse中web项目不自 ...

  2. 关于状态压缩DP以及状态压缩

    首先要明确:状态压缩是利用数字来代表一组序列的方法,从而降低序列访问的复杂度,本质上跟HASH有着差不多的思想,但是其实就是数位运算的一种 定义:集合中共有N个数字,其中每个数字均小于K,能么我们可以 ...

  3. .net core webapi框架

    折腾了一段时间..还是用ef比较熟,哈哈 参考地址:https://www.cnblogs.com/danvic712/p/10331976.html --jwt 参考地址:https://www.c ...

  4. 解决element-ui中el-menu组件作为vue-router模式在刷新页面后default-active属性与当前路由页面不一致问题的方法

    解决办法是给menu的default-active绑定route.path形如:<el-menu :default-active="$route.path" ...>每 ...

  5. JavaScript高级程序设计第三版-读书笔记(1-3章)

    这是我第一次用markdown,也是我第一次在网上记录我自己的学习过程. 第一章 JavaScript主要由以下三个不同的部分构成 ECMAScript   提供核心语言功能 DOM     提供访问 ...

  6. NIO2

    Files工具包下包含创建临时文件, 文件copy, move等API Path tempFile = Files.createTempFile(null, ".tmp"); // ...

  7. VS文档自动生成

    VS2008文档自动生成 (发现,Sandcastle主要是用于C#项目.里面的注释都是XML格式的.不太适合VC的.最终还是得用Doxygen) 一.Sandcastle简介: Sandcastle ...

  8. Spring学习(五)事务管理

    Spring 事务管理: 一.事务概念: 1.什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的 ...

  9. 湖南省第十二届大学生计算机程序设计竞赛 problem A 2016

    如果 a * b % 2016 == 0 如果a = 1 ,且 a * b % 2016 == 0 考虑一下a = 2017的时候 2017 * b = (2016 + 1) * b % 2016 = ...

  10. xmanger图形化登陆远程服务器

    由于网上的资料比较杂,经过本人整理实际操作验证,保证ok  本人的服务器系统为centos5.8 下面的都是centos服务器上的操作,需要简单的配置下: win客户端使用xmanger软件:首先是服 ...