redisTemplate 键值序列化策略
redisTemplate 键值序列化策略
RedisSerializer<T>
StringRedisSerializer
JdkSerializationRedisSerializer
keySerializer
valueSerializer
hashKeySerializer
hashValueSerializer
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
private boolean enableDefaultSerializer = true;
private RedisSerializer<?> defaultSerializer;
private RedisSerializer keySerializer = null;
private RedisSerializer valueSerializer = null;
private RedisSerializer hashKeySerializer = null;
private RedisSerializer hashValueSerializer = null;
private RedisSerializer<String> stringSerializer = new StringRedisSerializer();
/* redisTemplate 默认的序列化策略 */
public void afterPropertiesSet() {
super.afterPropertiesSet();
boolean defaultUsed = false;
if (defaultSerializer == null) {
defaultSerializer = new JdkSerializationRedisSerializer(
classLoader != null ? classLoader : this.getClass().getClassLoader());
}
if (enableDefaultSerializer) {
if (keySerializer == null) {
keySerializer = defaultSerializer;
defaultUsed = true;
}
if (valueSerializer == null) {
valueSerializer = defaultSerializer;
defaultUsed = true;
}
if (hashKeySerializer == null) {
hashKeySerializer = defaultSerializer;
defaultUsed = true;
}
if (hashValueSerializer == null) {
hashValueSerializer = defaultSerializer;
defaultUsed = true;
}
}
//启用默认序列化器并且默认序列化器被使用,检查默认序列化器为 null ,则序列化器没有全部初始化成功。
if (enableDefaultSerializer && defaultUsed) {
Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
}
if (scriptExecutor == null) {
this.scriptExecutor = new DefaultScriptExecutor<K>(this);
}
initialized = true;
}
}
keySerializer 字符串 哈希 列表 集合 有序集合的键的序列化策略。
valueSerializer 字符串 列表 集合 有序集合的值的序列化策略。
hashKeySerializer 哈希的小键的序列化策略
hashValueSerializer 哈希的值的序列化策略
StringRedisSerializer 只能是 String 对象
JdkSerializationRedisSerializer 实现了序列化接口的对象。
String 类型
RedisSerializer<T>
将一个对象序列化字节数组,存入 redis 。将 redis 得到的字节数组反序列化成对象。
public interface RedisSerializer<T> {
byte[] serialize(T t) throws SerializationException;
T deserialize(byte[] bytes) throws SerializationException;
}
@Test
public void testStrCR(){
redisTemplate.boundValueOps("用户名").set("刘备");
String username = (String) redisTemplate.boundValueOps("用户名").get();
System.out.println(username);//刘备
}
@Test
public void testStrD(){
redisTemplate.delete("用户名");
}
127.0.0.1:6379> keys *
1) "\xe7\x94\xa8\xe6\x88\xb7\xe5\x90\x8d" UTF-8 用户名
2) "\xd3\xc3\xbb\xa7\xc3\xfb" GBK 用户名
127.0.0.1:6379> get "\xd3\xc3\xbb\xa7\xc3\xfb" GBK 用户名
"\xe5\x88\x98\xe5\xa4\x87" UTF-8 刘备
127.0.0.1:6379> get "\xe7\x94\xa8\xe6\x88\xb7\xe5\x90\x8d" UTF-8 用户名
"\xe5\x88\x98\xe5\xa4\x87" UTF-8 刘备
/*
可见 redis 命令行打印就是字节数组的16进制形式。中文字符串 + 编码 = 字节数组。客户端发送给 redis 的是字节数组。
*/
@Test
public void x3() throws UnsupportedEncodingException {
byte[] bytesUTF8 = "用户名".getBytes("UTF-8");
System.out.println(bytesToHexString(bytesUTF8));//e794a8e688b7e5908d
byte[] bytesGBK = "用户名".getBytes("GBK");
System.out.println(bytesToHexString(bytesGBK));//d3c3bba7c3fb
byte[] bytes= "刘备".getBytes("UTF-8");
System.out.println(bytesToHexString(bytes));//e58898e5a487
}
常用字节转换(字符串转16进制,16进制转字符串)https://blog.csdn.net/yyz_1987/article/details/80634224
public static String bytesToHexString(byte[] src){
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
//原文:https://blog.csdn.net/yyz_1987/article/details/80634224
package org.springframework.data.redis.serializer;
public class StringRedisSerializer implements RedisSerializer<String> {
private final Charset charset;
public StringRedisSerializer() {
this(Charset.forName("UTF8"));
}
public StringRedisSerializer(Charset charset) {
Assert.notNull(charset);
this.charset = charset;
}
public String deserialize(byte[] bytes) {
return (bytes == null ? null : new String(bytes, charset));
}
public byte[] serialize(String string) {
return (string == null ? null : string.getBytes(charset));
}
}
修改 redisTemplate 键值的序列化策略
<!-- 配置RedisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<!-- 序列化策略 推荐使用StringRedisSerializer ,可以通过构造参数指定字符集,默认为 UTF-8 -->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer">
<constructor-arg ref="gbkCharSet" />
</bean>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean>
package com.mozq.charset;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
//@Component
@Configuration
public class CharSetUtil {
@Bean("gbkCharSet")
public Charset gbkCharSet(){
return Charset.forName("GBK");
}
}