【Redis】RedisTemplate和StringRedisTemplate的区别

13 篇文章 0 订阅
7 篇文章 0 订阅
两者的关系是 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 一样的序列化,使用起来更加灵活。

  • 15
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值