* redis虽然提供了对list set hash等数据类型的支持,但是没有提供对POJO对象的支持,底层都是把对象序列化后再以字符串的方式存储的。*
Spring data提供了若干个Serializer,主要包括:
- JdkSerializationRedisSerializer——使用Java自带的序列化机制将对象序列化为一个字符串
- OxmSerializer——将对象序列化为xml字符串
- Jackson2JsonRedisSerializer——将对象序列化为json字符串
下面分别测试这三种序列化,看看效果:
实体类User——将要保存到redis的对象
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "user")
public class User implements Serializable{
private static final long serialVersionUID = 5403379425407254942L;
@XmlAttribute
private String userName;
@XmlAttribute
private int age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
RootConfig配置类:
@Configuration
@ComponentScan(basePackages="com.redis.*")
public class RootConfig {
/**
* 配置redis连接工厂
* @return
*/
@Bean
public RedisConnectionFactory redisConnectionFactory(){
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName("localhost");
factory.setPort(6379);
factory.afterPropertiesSet();
return factory;
}
/**
* Spring的RedisTemplate
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(){
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(redisConnectionFactory());
return template;
}
@Bean
public OxmSerializer oxmSerializer(){
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
Map<String, Object> properties = new HashMap<String, Object>();//创建映射,用于设置Marshaller属性
properties.put(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);//放置xml自动缩进属性
properties.put(Marshaller.JAXB_ENCODING, "utf-8");
jaxb2Marshaller.setClassesToBeBound(User.class);//映射的xml类放入JAXB环境中
jaxb2Marshaller.setMarshallerProperties(properties);//设置Marshaller属性
return new OxmSerializer(jaxb2Marshaller, jaxb2Marshaller);
}
//下面是简单类型的序列化类
public static enum StringSerializer implements RedisSerializer<String> {
INSTANCE;
@Override
public byte[] serialize(String t) throws SerializationException {
return (null != t ? t.getBytes() : new byte[0]);
}
@Override
public String deserialize(byte[] bytes) throws SerializationException {
if(bytes.length > 0){
return new String(bytes);
} else {
return null;
}
}
}
public static enum LongSerializer implements RedisSerializer<Long> {
INSTANCE;
@Override
public byte[] serialize(Long t) throws SerializationException {
if(null != t){
return t.toString().getBytes();
}else {
return new byte[0];
}
}
@Override
public Long deserialize(byte[] bytes) throws SerializationException {
if(bytes.length > 0){
return Long.parseLong(new String(bytes));
}else {
return null;
}
}
}
public static enum IntSerializer implements RedisSerializer<Integer> {
INSTANCE;
@Override
public byte[] serialize(Integer t) throws SerializationException {
if(null != t){
return t.toString().getBytes();
}else {
return new byte[0];
}
}
@Override
public Integer deserialize(byte[] bytes) throws SerializationException {
if(bytes.length > 0){
return Integer.parseInt(new String(bytes));
}else {
return null;
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
测试用例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={RootConfig.class,WebConfig.class})
@WebAppConfiguration
public class KeyValueSerializersTest {
@Autowired
private RedisConnectionFactory connectionFactory;
@Autowired
private OxmSerializer oxmSerializer;
@Test
public void testJdkSerializer(){
RedisTemplate<String, Serializable> redis = new RedisTemplate<String, Serializable>();
redis.setConnectionFactory(connectionFactory);
redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);
redis.setValueSerializer(new JdkSerializationRedisSerializer());
redis.afterPropertiesSet();
ValueOperations<String, Serializable> ops = redis.opsForValue();
User user1 = new User();
user1.setUserName("xuexiaoqiang");
user1.setAge(25);
String key1 = "jdk/user1";
User user11 = null;
long begin = System.currentTimeMillis();
for(int i = 0; i < 100; i++){
ops.set(key1, user1);
user11 = (User) ops.get(key1);
}
long time = System.currentTimeMillis() - begin;
System.out.println("jdk time: "+time);
System.out.println(user11.getUserName());
}
@Test
public void testOxmSerializer() {
RedisTemplate<String, Object> redis = new RedisTemplate<String, Object>();
redis.setConnectionFactory(connectionFactory);
redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);
redis.setValueSerializer(oxmSerializer);
redis.afterPropertiesSet();
ValueOperations<String, Object> ops = redis.opsForValue();
User user1 = new User();
user1.setUserName("xuexiaoqiang");
user1.setAge(25);
String key1 = "oxm/user1";
User user11 = null;
long begin = System.currentTimeMillis();
for(int i = 0; i < 100; i++){
ops.set(key1, user1);
user11 = (User) ops.get(key1);
}
long time = System.currentTimeMillis() - begin;
System.out.println("oxm time: "+time);
System.out.println(user11.getUserName());
}
@Test
public void testJacksonSerialiable() {
RedisTemplate<String, Object> redis = new RedisTemplate<String, Object>();
redis.setConnectionFactory(connectionFactory);
redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);
redis.setValueSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
redis.afterPropertiesSet();
ValueOperations<String, Object> ops = redis.opsForValue();
User user1 = new User();
user1.setUserName("xuexiaoqiang");
user1.setAge(25);
String key1 = "json/user1";
User user11 = null;
long begin = System.currentTimeMillis();
for(int i = 0; i < 100; i++){
ops.set(key1, user1);
user11 = (User) ops.get(key1);
}
long time = System.currentTimeMillis() - begin;
System.out.println("json time: "+time);
System.out.println(user11.getUserName());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
结果:
testJdkSerializer()方法:
控制台打印:
jdk time: 68
xuexiaoqiang
- 1
- 2
redis中:
127.0.0.1:6379> get jdk/user1
"\xac\xed\x00\x05sr\x00\x15com.redis.entity.UserJ\xfc\xa8\xf5\x86\r\xc1\x9e\x02\x00\x02I\x00\x03ageL\x00\buserNamet\x00\x12Ljava/lang/String;xp\x00\x00\x00\x19t\x00\x0cxuexiaoqiang"
- 1
- 2
testOxmSerializer()方法:
控制台输出:
oxm time: 471
xuexiaoqiang
- 1
- 2
redis:
127.0.0.1:6379> get oxm/user1
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<user userName=\"xuexiaoqiang\" age=\"25\"/>\n"
- 1
- 2
testJacksonSerialiable()方法:
控制台输出:
json time: 97
xuexiaoqiang
- 1
- 2
- 3
redis:
127.0.0.1:6379> get json/user1
"{\"userName\":\"xuexiaoqiang\",\"age\":25}"
- 1
- 2
从时间上来看,JdkSerializationRedisSerializer是最高效的,但是从序列化的结果来看,json占用的内存最小。所以个人认为最优方案是使用JSON序列化。