当前位置:   article > 正文

【Redis】RedisTemplate和StringRedisTemplate的区别_redistemplate stringredistemplate

redistemplate stringredistemplate
两者的关系是 StringRedisTemplate 继承 RedisTemplate 。
两者的数据是不共通的:也就是说 StringRedisTemplate 只能管理 StringRedisTemplate 里面的数据,RedisTemplate 只能管理 RedisTemplate 中的数据。

RedisTemplate 看这个类的名字后缀是 Template ,如果了解过 Spring 如何连接关系型数据库的,大概不会难猜出这个类是做什么的 ,它跟 JdbcTemplate 一样封装了对Redis的一些常用的操作,当然 StringRedisTemplate 跟 RedisTemplate 功能类似那么肯定就会有人问,为什么会需要两个Template呢,一个不就够了吗?其实他们两者之间的区别主要在于他们使用的序列化类是不同的。

  • StringRedisTemplate 的API假定所有的数据类型化都是字符类型,即key和value都是字符串类型。默认采用的是 String 的序列化策略,即 StringRedisSerializer ,保存的key和value都是采用此策略序列化保存的。
  • RedisTemplate 默认采用的是JDK的序列化策略,即 JdkSerializationRedisSerializer ,保存的key和value都是采用此策略序列化保存的。

RedisTemplate 默认使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组然后在存入 Redis 数据库,这个时候打开 Redis 查看的时候,你会看到你的数据不是以可读的形式展现的,而是以字节数组显示,类似下面:

StringRedisTemplate 默认存入的数据就是原文,因为 StringRedisTemplate 默认使用的是 String 序列化策略,使用 StringRedisTemplate 默认存入数据长这个样:

造成两者差异的原因是因为在初始化时,两者使用的序列化策略不同导致的,翻开源码可以看到,如下:

  1. public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
  2. private boolean enableTransactionSupport = false;
  3. private boolean exposeConnection = false;
  4. private boolean initialized = false;
  5. private boolean enableDefaultSerializer = true;
  6. @Nullable
  7. private RedisSerializer<?> defaultSerializer;
  8. @Nullable
  9. private RedisSerializer keySerializer = null;
  10. @Nullable
  11. private RedisSerializer valueSerializer = null;
  12. @Nullable
  13. private RedisSerializer hashKeySerializer = null;
  14. @Nullable
  15. private RedisSerializer hashValueSerializer = null;
  16. // 其它字段略...
  17. public RedisTemplate() {
  18. }
  19. // 该方法是重写RedisAccessor的方法 RedisAccessor实现了spring的InitializingBean 也就是在启动时会执行该方法 可以看到该方法默认的序列化为JdkSerializationRedisSerializer
  20. public void afterPropertiesSet() {
  21. super.afterPropertiesSet();
  22. boolean defaultUsed = false;
  23. if (this.defaultSerializer == null) {
  24. this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
  25. }
  26. if (this.enableDefaultSerializer) {
  27. if (this.keySerializer == null) {
  28. this.keySerializer = this.defaultSerializer;
  29. defaultUsed = true;
  30. }
  31. if (this.valueSerializer == null) {
  32. this.valueSerializer = this.defaultSerializer;
  33. defaultUsed = true;
  34. }
  35. if (this.hashKeySerializer == null) {
  36. this.hashKeySerializer = this.defaultSerializer;
  37. defaultUsed = true;
  38. }
  39. if (this.hashValueSerializer == null) {
  40. this.hashValueSerializer = this.defaultSerializer;
  41. defaultUsed = true;
  42. }
  43. }
  44. if (this.enableDefaultSerializer && defaultUsed) {
  45. Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");
  46. }
  47. if (this.scriptExecutor == null) {
  48. this.scriptExecutor = new DefaultScriptExecutor(this);
  49. }
  50. this.initialized = true;
  51. }
  52. // 其余方法略...
  53. }

可以看到 RedisTemplate 在初始化时是无参构造,通过 Spring 的 Bean 加载机制在项目启动时执行afterPropertiesSet来完成序列化设置,如果需要自定义序列化配置,可以自己写一个 RedisTemplate 的Bean,来完成配置。

  1. @Configuration
  2. public class RedisConfig {
  3. @Bean
  4. public RedisTemplate<String,Object> redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory) {
  5. // 创建RedisTemplate
  6. RedisTemplate<String,Object> redisTemplate = new RedisTemplate<String,Object>();
  7. // 字符串和JDK序列化器
  8. RedisSerializer<String> strSerializer = RedisSerializer.string();
  9. RedisSerializer<Object> jdkSerializer = RedisSerializer.java();
  10. // 设置键值序列化器
  11. redisTemplate.setKeySerializer(strSerializer);
  12. redisTemplate.setValueSerializer(jdkSerializer);
  13. // 设置哈希字段和值序列化器
  14. redisTemplate.setHashKeySerializer(strSerializer);
  15. redisTemplate.setHashValueSerializer(jdkSerializer);
  16. // 给redisTemplate设置连接工厂
  17. redisTemplate.setConnectionFactory(redisConnectionFactory);
  18. return redisTemplate;
  19. }
  20. }

StringRedisTemplate 就比较简单了,直接继承了 RedisTemplate,在初始化时默认使用了 String 序列化,源码如下:

  1. public class StringRedisTemplate extends RedisTemplate<String, String> {
  2. public StringRedisTemplate() {
  3. this.setKeySerializer(RedisSerializer.string());
  4. this.setValueSerializer(RedisSerializer.string());
  5. this.setHashKeySerializer(RedisSerializer.string());
  6. this.setHashValueSerializer(RedisSerializer.string());
  7. }
  8. // 其他方法略...
  9. }

那么就可以得出一个结论,如果你想使用默认的配置来操作 Redis,则如果操作的数据是字节数组,就是用RedisTemplate,如果操作的数据是明文,使用 StringRedisTemplate

当然在项目中真实使用时,一般是自定义 RedisTemplate 的 Bean 实例,来设置具体的序列化策略,说白了就是 RedisTemplate 通过自定义 Bean 可以实现和 StringRedisTemplate 一样的序列化,使用起来更加灵活。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/575972
推荐阅读
相关标签
  

闽ICP备14008679号