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.
圖形化介面:大概證實了我的想法。