一,前言
本篇文章主要来实现在如何在SpringBoot中将对象缓存到redis中。另外对于SpringBoot整合Redis有不清楚的地方可以查看这篇文章SpringBoot整合Redis
二,不同序列化方法
1打开我们引入的Redis自动配置类:
RedisAutoConfiguration,可以看到有两种方法
- RedisTemplate :以对象的形式来存放数据
- StringRedisTemplate:以字符串的形式来存放数据
两者区别主要在于使用了不同的序列化方法:
- RedisTemplate默认使用JdkSerializationRedisSerializer序列化方法,将对象以序列化后的形式缓存
- StringRedisTemplate使用了StringRedisSerializer序列化方法,将数据以字符串的形式保存缓存
三,测试:
现有环境:
(使用Mybatis注解版对Mysql数据库进行操作)
场景测试一:
将查询出来的student对象使用RedisTemplate缓存
class DemoBestStarterTestApplicationTests {
@Autowired //操作字符串常用,进行序列化
StringRedisTemplate stringRedisTemplate;
@Autowired //kv 对象
RedisTemplate redisTemplate;
@Autowired
RedisTemplate<Object,Student> StudentRedisTemplate;
@Test
void contextLoads() {
//String
/*
opsForValue()(String 字符串)
opsForList()(List 列表)
opsForSet() (set 集合)
opsForHash() (hash )
opsForZSet() (ZSet 有序集合)
*/
Student student=studentMapper.getStudentById(2,138);
redisTemplate.opsForValue().set("x1",student);
System.out.println();
}
}
结果会报异常:
org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.best.demobeststartertest.Cache.bean.Student]
原因:未对student类进行序列化
2对student类实现序列化接口,在测试:
测试成功,但是我们可以发现,我们的对象是被以序列化之后的形式存储的,那如果我们为了想要以对象存储,又该如何实现呢?
答案很简单,我们可以通过自定义一个RedisTemplate泛型接口实现类,来自定义序列化方法
- 打开RedisAutoConfiguration,复制RedisTemplate泛型方法
- 查看RedisTemplate泛型类 查看该RedisTemplate下的序列化设置:
setDefaultSerializer(),采用的是JdkSerializationRedisSerializer序列化方法 - 打开RedisSerializer泛型可以发现,该有多种实现类
- 可以看到图中的Jackson2JsonRedisSerializer类,我们选用该方法,如下代码,创建该序列化对象,并赋值给RedisTemplate的序列化设置方法
//自定义序列化方法
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object, Student> StudentRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Student> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
//序列化器
Jackson2JsonRedisSerializer<Student> ser= new Jackson2JsonRedisSerializer<Student>(Student.class);
template.setDefaultSerializer(ser);
return template;
}
}
#################测试类#############################
@SpringBootTest
class DemoBestStarterTestApplicationTests {
@Autowired //操作字符串常用,进行序列化
StringRedisTemplate stringRedisTemplate;
@Autowired
StudentMapper studentMapper;
@Autowired //kv 对象
RedisTemplate redisTemplate;
@Autowired
RedisTemplate<Object,Student> StudentRedisTemplate;
@Test
void contextLoads() {
//String
/*
opsForValue()(String 字符串)
opsForList()(List 列表)
opsForSet() (set 集合)
opsForHash() (hash )
opsForZSet() (ZSet 有序集合)
*/
Student student=studentMapper.getStudentById(2,138);
redisTemplate.opsForValue().set("x1",student);
StudentRedisTemplate.opsForValue().set("x2",student);
System.out.println();
}
}
5.测试结果
可以看到图中,我们插入的x2就是通过Jackson2JsonRedisSerializer序列化方法实现的对象存储
x1是通过默认序列化方法实现的对象序列化存储