java存取redis采用RuntimeSchema序列化工具类高效转化及理解

在java中利用jedis操纵redis,这里外加jedis的线程池高效管理资源:

mvn配置jedis和序列换工具类的依赖:

        <!--jdedis依赖-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.7.3</version>
        </dependency>
        <!-- 序列换依赖 -->
        <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>

在spring工程中加入写好的RedisDao的bean,上面的是连接池的配置,下面就是自己马上要写的redisdao。

<bean id="redisConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
        <property name="maxTotal" value="${redis.maxTotal}"/>
    </bean>
    <!--RedisDao-->
    <bean id="redisCacheDao" class="cn.wzy.sport.dao.impl.RedisDao">
        <constructor-arg name="config" ref="redisConfig"/>
        <constructor-arg name="ip" value="${redis.host}"/>
        <constructor-arg name="port" value="${redis.port}"/>
        <constructor-arg name="password" value="${redis.password}"/>
    </bean>
package cn.wzy.sport.dao.impl;

import cn.wzy.sport.entity.User_Info;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
import lombok.extern.log4j.Log4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Created by Wzy
 * on 2018/6/4
 */
@Log4j
public class RedisDao {

	private final JedisPool jedisPool;
	private final String pwd;

	public RedisDao(JedisPoolConfig config, String ip, int port, String password) {
		pwd = password;
		jedisPool = new JedisPool(config, ip, port);
	}

	private final RuntimeSchema<User_Info> schema = RuntimeSchema.createFrom(User_Info.class);

	public User_Info getUser(int userId) {
		try {
			Jedis jedis = jedisPool.getResource();
			jedis.auth(pwd);
			try {
				String key = "user:" + userId;
				byte[] bytes = jedis.get(key.getBytes());
				if (bytes != null) {
					User_Info user = schema.newMessage();
					ProtostuffIOUtil.mergeFrom(bytes, user, schema);
					return user;
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				jedis.close();
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}

	public String putUser(User_Info record) {
		try {
			Jedis jedis = jedisPool.getResource();
			jedis.auth(pwd);
			try {
				String key = "user:" + record.getId();
				byte[] bytes = ProtostuffIOUtil.toByteArray(record, schema
					, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
				String result = jedis.setex(key.getBytes(), 3600, bytes);
				return result;
			} finally {
				jedis.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

RuntimeSchema<User_Info>是一个专门为User_Info准备的高效序列化第三方工具类,比自带的序列化速度快,内存更省。

存取的时候是通过序列化工具类把对象序列化成一个字节数组,再把这个数据存到redis中。

LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE)的作用就是外加一个缓冲区,加快序列化速度。

byte[] bytes = ProtostuffIOUtil.toByteArray(record, schema
                    , LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));

取得时候也是这样,获取出字节数组,在通过序列化工具反序列化到对象中:注意:先通过序列化生成一个空对象,然后在进行字节数组反向赋值。

User_Info user = schema.newMessage();
           ProtostuffIOUtil.mergeFrom(bytes, user, schema);

以前不是很懂为什么可以通过字节数组来存对象,存进去以后又是以什么数据类型存储的呢?最近下载了一个redis的可视化软件,然后登录redis看看存到什么位置了。

测试的时候存了一个id为13的对象进去,发现他就是一个普通的key-value的数据,只是value变成了一个乱字符串(我想应该是对象的字节数组转成string的缘故吧):

然而发现加了一个文件夹?我当时不懂这个是什么数据结构,后来自己到命令行用get user:13尝试获取这个对象,发现没毛病,能获取出来,后来手动加了一个user:14进去:

成了这个结果,大概懂了,可视化的文件夹应该是为了方便观看,把前缀一样的对象放在一级中。

又开始存一个对象user:12:12.

图形化界面:大概证实了我的想法。

 

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值