Redis+protostuff 实现对象序列化保存,反序列化获取

很多情况我们为了解决并发问题使用redis非关系型数据库保存数据,我们序列化保存方便数据的传输 可以随时把对象持久化到数据库、文件等系统里,也方我们反序列化获取对象,下面我就开始整理吧
1.利用maven管理项目,导入相关jar包
< dependency >
< groupId > redis.clients groupId >
< artifactId > jedis artifactId >
< version > 2.9.0 version >
dependency >
< dependency >
< groupId > com.dyuproject.protostuff groupId >
< artifactId > protostuff-core artifactId >
< version > 1.1.1 version >
dependency >
< dependency >
< groupId > com.dyuproject.protostuff groupId >
< artifactId > protostuff-runtime artifactId >
< version > 1.1.1 version >
dependency >
2.编写protostuff工具类,实现对象序列化和反序列化
package hxf.utils;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtobufIOUtil;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
/**
* 序列化工具类
*/
public class ProtostuffUtil {
public ProtostuffUtil() {
}

/**
* 对象序列化
* @param o 需要序列化对象
* @param 序列化对象类型
* @return
*/
public static < T > byte [] serializer( T o) {
Schema schema = RuntimeSchema. getSchema (o.getClass()); //通过对象的类构建对应的schema
return ProtobufIOUtil. toByteArray (o, schema, LinkedBuffer. allocate (LinkedBuffer. DEFAULT_BUFFER_SIZE )); //保存数据
}

/**
* 对象反序列化
* @param bytes 对象字节数组
* @param clazz Class对象
* @param 反序列化对象
* @return
*/
public static < T > T deserializer( byte [] bytes, Class< T > clazz) {
T obj = null ;
try {
Schema schema = RuntimeSchema. getSchema (clazz); //通过对象的类构建对应的schema;
obj = ( T ) schema.newMessage(); //通过schema新建一个对象,这里需要转换一下
ProtostuffIOUtil. mergeFrom (bytes, obj, schema); //数据反序列化
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
}
3.redis 操作方法
package hxf.redis.dao.impl;

import hxf.entity.Seckill;
import hxf.redis.dao.RedisDataSource;
import hxf.utils.ProtostuffUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation. Autowired ;
import org.springframework.stereotype. Repository ;
import redis.clients.jedis.ShardedJedis;

@Repository
public class RedisClientTemplate {
private Logger logger = LoggerFactory. getLogger ( this .getClass());
@Autowired
private RedisDataSource redisDataSource ;
public void disconnect() {
ShardedJedis shardedJedis = redisDataSource .getRedisClient();
shardedJedis.disconnect();
}
private static final Logger log = LoggerFactory. getLogger (RedisClientTemplate. class );

/**
* 添加一个对象
* @param id 主键id
* @param o 对象数据
* @param 对象泛型
* @return 成功返回true,否则返回false
*/
public < T > boolean setObj(String id, T o) {
boolean result = false ;
ShardedJedis shardedJedis = redisDataSource .getRedisClient();
if (shardedJedis == null ) {
return result;
}
try {
String result1 = shardedJedis.set(id.getBytes(), ProtostuffUtil. serializer (o));
logger .info( "添加结果:" +result1);
if (result1.equals( "ok" )){
result = true ;
}
} catch (Exception e) {
log .error(e.getMessage(), e);
} finally {
redisDataSource .close(shardedJedis,!result);
}
return result;
}

public < T > T getObj(String id, Class< T > clazz) {
T result = null ;
ShardedJedis shardedJedis = redisDataSource .getRedisClient();
if (shardedJedis == null ) {
return result;
}
try {
byte [] bytes = shardedJedis.get(id.getBytes());
if (bytes != null ){
result = ProtostuffUtil. deserializer (bytes,clazz);
}
logger .info(bytes.toString());
} catch (Exception e) {
log .error(e.getMessage(), e);
} finally {

redisDataSource .close(shardedJedis);
}
return result;
}}
5.测试
package hxf.redis.dao.impl;
import hxf.entity.Seckill;
import junit.framework.TestCase;
import org.junit. Test ;
import org.springframework.beans.factory.annotation. Autowired ;
import org.junit.runner. RunWith ;
import org.springframework.test.context. ContextConfiguration ;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith (SpringJUnit4ClassRunner. class )
//配置Spring文件
@ContextConfiguration ({ "classpath:spring/spring-redis.xml" })
public class RedisClientTemplateTest extends TestCase {
@Autowired
private RedisClientTemplate redisClientTemplate ;
@Test
public void test() throws Exception {
Seckill seckill = new Seckill();
seckill.setSeckillId( 1002 );
seckill.setName( "100元秒杀苹果8" );
seckill.setNumber( 20 );
redisClientTemplate .setObj(seckill.getSeckillId()+ "" ,seckill);
}

@Test
public void testGet() throws Exception {
System. out .println( redisClientTemplate .getObj( "1002" ,Seckill. class ));
}
}
总结:这个方法适合存储对象,因为重点是redis保存数据时序列化与获取数据反序列化,redis的相关配置我没写出来,想在的redis配置的自己看这篇文章 https://www.cnblogs.com/tankaixiong/p/3660075.html

本文参考 http://blog.csdn.net/zhglance/article/details/56017926

你可能感兴趣的:(java,redis,protostuff,序列化)