日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

【Redis】RedisTemplate和StringRedisTemplate的區別

作者:Mr.VK 更新時間: 2024-03-09 編程語言
兩者的關系是 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 默認存入數據長這個樣:

造成兩者差異的原因是因為在初始化時,兩者使用的序列化策略不同導致的,翻開源碼可以看到,如下:

public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
    private boolean enableTransactionSupport = false;
    private boolean exposeConnection = false;
    private boolean initialized = false;
    private boolean enableDefaultSerializer = true;
    @Nullable
    private RedisSerializer<?> defaultSerializer;
    @Nullable
    private RedisSerializer keySerializer = null;
    @Nullable
    private RedisSerializer valueSerializer = null;
    @Nullable
    private RedisSerializer hashKeySerializer = null;
    @Nullable
    private RedisSerializer hashValueSerializer = null;
    // 其它字段略...
 
    public RedisTemplate() {
    }
 
 
    // 該方法是重寫RedisAccessor的方法 RedisAccessor實現了spring的InitializingBean 也就是在啟動時會執行該方法 可以看到該方法默認的序列化為JdkSerializationRedisSerializer
    public void afterPropertiesSet() {
        super.afterPropertiesSet();
        boolean defaultUsed = false;
        if (this.defaultSerializer == null) {
            this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
        }
 
        if (this.enableDefaultSerializer) {
            if (this.keySerializer == null) {
                this.keySerializer = this.defaultSerializer;
                defaultUsed = true;
            }
 
            if (this.valueSerializer == null) {
                this.valueSerializer = this.defaultSerializer;
                defaultUsed = true;
            }
 
            if (this.hashKeySerializer == null) {
                this.hashKeySerializer = this.defaultSerializer;
                defaultUsed = true;
            }
 
            if (this.hashValueSerializer == null) {
                this.hashValueSerializer = this.defaultSerializer;
                defaultUsed = true;
            }
        }
 
        if (this.enableDefaultSerializer && defaultUsed) {
            Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");
        }
 
        if (this.scriptExecutor == null) {
            this.scriptExecutor = new DefaultScriptExecutor(this);
        }
 
        this.initialized = true;
    }
    // 其余方法略...
}

可以看到 RedisTemplate 在初始化時是無參構造,通過 Spring 的 Bean 加載機制在項目啟動時執行afterPropertiesSet來完成序列化設置,如果需要自定義序列化配置,可以自己寫一個 RedisTemplate 的Bean,來完成配置。

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory) {
        // 創建RedisTemplate
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<String,Object>();
        // 字符串和JDK序列化器
        RedisSerializer<String> strSerializer = RedisSerializer.string();
        RedisSerializer<Object> jdkSerializer = RedisSerializer.java();
        // 設置鍵值序列化器
        redisTemplate.setKeySerializer(strSerializer);
        redisTemplate.setValueSerializer(jdkSerializer);
        // 設置哈希字段和值序列化器
        redisTemplate.setHashKeySerializer(strSerializer);
        redisTemplate.setHashValueSerializer(jdkSerializer);
        // 給redisTemplate設置連接工廠
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }
}

StringRedisTemplate 就比較簡單了,直接繼承了 RedisTemplate,在初始化時默認使用了 String 序列化,源碼如下:

public class StringRedisTemplate extends RedisTemplate<String, String> {
    public StringRedisTemplate() {
        this.setKeySerializer(RedisSerializer.string());
        this.setValueSerializer(RedisSerializer.string());
        this.setHashKeySerializer(RedisSerializer.string());
        this.setHashValueSerializer(RedisSerializer.string());
    }
    // 其他方法略...
}

那么就可以得出一個結論,如果你想使用默認的配置來操作 Redis,則如果操作的數據是字節數組,就是用RedisTemplate,如果操作的數據是明文,使用 StringRedisTemplate

當然在項目中真實使用時,一般是自定義 RedisTemplate 的 Bean 實例,來設置具體的序列化策略,說白了就是 RedisTemplate 通過自定義 Bean 可以實現和 StringRedisTemplate 一樣的序列化,使用起來更加靈活。

原文鏈接:https://blog.csdn.net/Mr_VK/article/details/136363773

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新