一,前言

本篇文章主要来实现在如何在SpringBoot中将对象缓存到redis中。另外对于SpringBoot整合Redis有不清楚的地方可以查看这篇文章SpringBoot整合Redis

二,不同序列化方法

1打开我们引入的Redis自动配置类:
RedisAutoConfiguration,可以看到有两种方法

  1. RedisTemplate :以对象的形式来存放数据
  2. 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泛型接口实现类,来自定义序列化方法

  1. 打开RedisAutoConfiguration,复制RedisTemplate泛型方法
  2. 查看RedisTemplate泛型类 查看该RedisTemplate下的序列化设置:
    setDefaultSerializer(),采用的是JdkSerializationRedisSerializer序列化方法
  3. 打开RedisSerializer泛型可以发现,该有多种实现类
  4. 可以看到图中的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是通过默认序列化方法实现的对象序列化存储

springboot redis 配置缓存数据不被序列化 springboot整合redis缓存_spring