GitHub超9万星标!三种序列化方式存取redis的方法,限时免费开源

50 篇文章 0 订阅

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

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

所以我选择了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;
        }
    });
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值