spring-redis序列化
(一)spring data redis 提供了多種可選擇策略(RedisSerializer)
- JdkSerializationRedisSerializer:POJO物件的存取場景,使用JDK本身序列化機制,將pojo類通過ObjectInputStream/ObjectOutputStream進行序列化操作,最終redis-server中將儲存位元組序列。是目前最常用的序列化策略。
- StringRedisSerializer:Key或者value為字串的場景,根據指定的charset對資料的位元組序列編碼成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封裝。是最輕量級和高效的策略。
- JacksonJsonRedisSerializer:jackson-json工具提供了javabean與json之間的轉換能力,可以將pojo例項序列化成json格式儲存在redis中,也可以將json格式的資料轉換成pojo例項。因為jackson工具在序列化和反序列化時,需要明確指定Class型別,因此此策略封裝起來稍微複雜。【需要jackson-mapper-asl工具支援】
- OxmSerializer:提供了將javabean與xml之間的轉換能力,目前可用的三方支援包括jaxb,apache-xmlbeans;redis儲存的資料將是xml工具。不過使用此策略,程式設計將會有些難度,而且效率最低;不建議使用。【需要spring-oxm模組的支援】
(出自: Spring data redis-StringRedisTemplate 用法)
spring-data-redis提供了多種serializer策略,這對使用jedis的開發者而言,實在是非常便捷。sdr提供了4種內建的serializer:
- JdkSerializationRedisSerializer:使用JDK的序列化手段(serializable介面,ObjectInputStrean,ObjectOutputStream),資料以位元組流儲存
- StringRedisSerializer:字串編碼,資料以string儲存
- JacksonJsonRedisSerializer:json格式儲存
- OxmSerializer:xml格式儲存
其中JdkSerializationRedisSerializer和StringRedisSerializer是最基礎的序列化策略,其中“JacksonJsonRedisSerializer”與“OxmSerializer”都是基於stirng儲存,因此它們是較為“高階”的序列化(最終還是使用string解析以及構建java物件)。
RedisTemplate中需要宣告4種serializer,預設為“JdkSerializationRedisSerializer”:
1) keySerializer :對於普通K-V操作時,key採取的序列化策略
2) valueSerializer:value採取的序列化策略
3) hashKeySerializer: 在hash資料結構中,hash-key的序列化策略
4) hashValueSerializer:hash-value的序列化策略
無論如何,建議key/hashKey採用StringRedisSerializer。
接下來,通過例項描述如何使用它們,可以首先參考“spring-data-redis特性”:
取自:
pring-data-redis: serializer例項
(二)嘗試其中三種
-
@Bean
-
public RedisTemplate<String, Object> jdkRedisTemplate(
-
RedisConnectionFactory factory) {
-
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
-
template.setConnectionFactory(factory);
-
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
-
ObjectMapper om = new ObjectMapper();
-
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
-
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
-
jackson2JsonRedisSerializer.setObjectMapper(om);
-
JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
-
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
-
template.setValueSerializer(jdkSerializationRedisSerializer);
-
template.setKeySerializer(stringRedisSerializer);
-
template.setHashKeySerializer(stringRedisSerializer);
-
template.setHashValueSerializer(jdkSerializationRedisSerializer);
-
template.afterPropertiesSet();
-
return template;
-
}
-
@Resource(name = "jdkRedisTemplate") // if stringRedisTemplate, result in SmsCheck cannot be cast to java.lang.String
-
private RedisTemplate<String, Object> jdkRedisTemplate;
-
@RequestMapping(value = "testRedis", method = RequestMethod.POST)
-
@ResponseBody
-
@ApiImplicitParams({})
-
@ApiOperation(value="testRedis")
-
public Object testRedis() {
-
SmsCheck smsCheck = new SmsCheck();
-
smsCheck.setMobile("xxx");
-
// 設定快取
-
jdkRedisTemplate.opsForValue().set("test",smsCheck);
-
return null;
-
}
-
@Entity
-
public class SmsCheck implements Serializable {
-
private static final long serialVersionUID = 1L;
-
@Id
-
@GeneratedValue(strategy = GenerationType.AUTO)
-
@Column(name = "sms_check_id")
-
private int smsCheckId;
-
private String mobile;
-
。。。。。。
僅對value操作,保持key為string序列化
1.jdk序列化方案
get test 顯示
"\xac\xed\x00\x05sr\x00\x1ecom.ilex.xxx.model.SmsCheck\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x05I\x00\nsmsCheckIdL\x00\acontentt\x00\x12Ljava/lang/String;L\x00\ncreateDatet\x00\x10Ljava/util/Date;L\x00\x06mobileq\x00~\x00\x01L\x00\x04typeq\x00~\x00\x01xp\x00\x00\x00\x00ppt\x00\x03xxxp"
注意:若這裡的SmsCheck未實現Serializable介面,會丟擲一個異常
2.string
直接丟擲異常
SmsCheck cannot be cast to java.lang.String
3 json
"[\"com.xxx.xx.model.SmsCheck\",{\"smsCheckId\":0,\"mobile\":\"xxx\",\"type\":null,\"content\":null,\"createDate\":null}]"
然後將key的序列化改為jdk
1) "\xac\xed\x00\x05t\x00\x04test"
2) "test"
顯示key也被jdk序列化了
redistemplate 預設用jdk序列化key和value
stringredistemplate預設用string序列化key和value
(三)關於序列化後redis檢視主要參考此貼:
最近在開始在學習Redis以及如何在Java當中去使用Redis,Redis是什麼我這裡就不說了。
我主要想說的是Redis和Java當中Spring結合起來的時候,使用到的RedisTemplate和StringRedisTemplate
他們兩者之間的區別,以及該怎麼使用。
RedisTemplate看這個類的名字字尾是Template,如果瞭解過Spring如何連線關係型資料庫的,大概不會難猜出這個類
是做什麼的 ,它跟JdbcTemplate一樣封裝了對Redis的一些常用的操作,當然StringRedisTemplate跟RedisTemplate功能類似
那麼肯定就會有人問,為什麼會需要兩個Template呢,一個不就夠了嗎?
其實他們兩者之間的區別主要在於他們使用的序列化類。
RedisTemplate使用的是JdkSerializationRedisSerializer
StringRedisTemplate使用的是StringRedisSerializer
RedisTemplate使用的序列類在在操作資料的時候,比如說存入資料會將資料先序列化成位元組陣列
然後在存入Redis資料庫,這個時候開啟Redis檢視的時候,你會看到你的資料不是以可讀的形式
展現的,而是以位元組陣列顯示,類似下面
當然從Redis獲取資料的時候也會預設將資料當做位元組陣列轉化,這樣就會導致一個問題,當需要獲取的
資料不是以位元組陣列存在redis當中而是正常的可讀的字串的時候,比如說下面這種形式的資料
關於RedisTemplate和StringRedisTemplate
(四)另外:
spring-data-redis是對jedis的封裝,如果直接使用jedis,需手動
1序列化物件
2轉為json字串
使用,spring自動處理了
jedis操作: