redis中如何存储java对象
根据 redis 的存储原理,Redis 的 key 和 value 都支持二进制安全的字符串
1. 利用序列化和反序列化的方式
存储 java 对象我们可以通过对象的序列化与反序列化完成存储于取出, 这样就可以使用 redis 存储 java 对象了
a. 利用 jdk 自带的序列化机制,但效率不高
步骤: 创建一个序列化和反序列化的工具类
public class SerializeUtil { 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) { } return null; } 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) { } return null; } }
b. 利用谷歌的序列化依赖,高效,使用于秒杀等业务场景
<!--prostuff 序列化依赖 -->
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.0.8</version>
</dependency>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.0.8</version>
</dependency>
@Slf4j public class RedisDao {</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">final</span><span style="color: rgba(0, 0, 0, 1)"> JedisPool jedisPool; </span><span style="color: rgba(0, 0, 255, 1)">private</span> RuntimeSchema<Seckill> schema = RuntimeSchema.createFrom(Seckill.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">public</span> RedisDao(String ip, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> port) { jedisPool </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> JedisPool(ip, port); } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Seckill getSeckill(Long seckillId) { Jedis jedis </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { jedis </span>=<span style="color: rgba(0, 0, 0, 1)"> jedisPool.getResource(); String key </span>= "seckill:" +<span style="color: rgba(0, 0, 0, 1)"> seckillId; </span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bytes =<span style="color: rgba(0, 0, 0, 1)"> jedis.get(key.getBytes()); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (bytes != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { Seckill seckill </span>=<span style="color: rgba(0, 0, 0, 1)"> schema.newMessage(); ProtostuffIOUtil.mergeFrom(bytes, seckill, schema); </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> seckill; } } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) { log.error(e.getMessage(), e); } </span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 0, 255, 1)">if</span> (jedis != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { jedis.close(); } } </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String putSeckill(Seckill seckill) { Jedis jedis </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { jedis </span>=<span style="color: rgba(0, 0, 0, 1)"> jedisPool.getResource(); String key </span>= "seckill:" +<span style="color: rgba(0, 0, 0, 1)"> seckill.getSeckillId(); </span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bytes =<span style="color: rgba(0, 0, 0, 1)"> ProtostuffIOUtil.toByteArray(seckill, schema, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE)); Integer timeout </span>= 60 * 60<span style="color: rgba(0, 0, 0, 1)">; String result </span>=<span style="color: rgba(0, 0, 0, 1)"> jedis.setex(key.getBytes(), timeout, bytes); </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result; } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) { log.error(e.getMessage(), e); } </span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 0, 255, 1)">if</span> (jedis != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { jedis.close(); } } </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; }
}