RedisTemplate 和 StringRedisTemplate 的区别及个人见解
@[toc]
一、区别
<font color='red'>区别点 1:</font>两者的关系是 StringRedisTemplate 继承 RedisTemplate。RedisTemplate 是一个泛型类,而 StringRedisTemplate 则不是。
<font color='red'>区别点 2:</font>两者序列化策略不同,StringRedisTemplate 默认采用的是 String 的序列化策略,保存的 key 和 value 都是采用此策略序列化保存的。RedisTemplate 默认采用的是 JDK 的序列化策略,保存的 key 和 value 都是采用此策略序列化保存的。
<font color='red'>区别点 3:(疑惑点)</font>两者的数据是不共通的;也就是说 StringRedisTemplate 只能管理 StringRedisTemplate 里面的数据,RedisTemplate 只能管理 RedisTemplate 中的数据。
<font color='red'>区别点 4:</font>StringRedisTemplate 只能对 key=String,value=String 的键值对进行操作,RedisTemplate 可以对任何类型的 key-value 键值对操作。
二、问题总结
问题 1:究竟是数据隔离?还是存入的数据访问不到?用词是否严谨?
<font color='red'>答案:</font>严谨说并不是数据隔离,而应该说成是彼此存入 redis 的数据存在,但是访问不到;而数据隔离通常指的是数据存在同一个库下,但是自己只能查看并访问自己的数据,而 redis 中数据都能看到且只是使用不同 RedisTemplate 和 StringRedisTemplate 对象彼此访问不到而已。
问题 2:(重要)我自己测试 RedisTemplate 和 StringRedisTemplate 居然都可以彼此访问到存取的字符串值,为啥?别人文章说数据不共通
<font color='red'>答案:</font>所谓的彼此访问不到数据,前提是自己不重新对 RedisTemplate 进行序列化设置,<font color='red'>大白话讲就是直接使用默认的,这样才能实现彼此数据隔离访问不到</font>,而实现了序列化后 RedisTemplate 和 StringRedisTemplate 对字符串类型数据就都能获取了。
而我的能访问到就是我对 RedisTemplate 进行了序列化设置,比如如下代码,<font color='red'>注意这一行: template.setKeySerializer(RedisSerializer.string());</font>这样设置后就<font color='red'>会导致 RedisTemplate 和 StringRedisTemplate 针对 string 类型的属性值使用了相同的序列化方式</font>,这样就能彼此访问到数据了;反之不设置这一行,就会彼此反问不到数据。
问题 3:.源码分析 RedisTemplate 和 StringRedisTemplate 的序列化方式
RedisTemplate 的序列化
StringRedisTemplate 的序列化
问题 4:.RedisTemplate 和 StringRedisTemplate 使用默认序列化方式存值区别在哪?仍然使用如下代码,只不过自己不设置序列化使用默认值
结果如下:
可以发现 stringRedisTemplate 存入的还是字符串样式,能直接看出属性值为 def,<font color='red'>然而 RedisTemplate 存入的 key 值前面居然多加了一串 16 进制的字符串值,同时存入 redis 的结果也是转换为字节数组 bytes 之后的看不懂的值</font>。
stringRedisTemplate
RedisTemplate
问题 5:.RedisTemplate 和 StringRedisTemplate 存入 redis 的字符串类型不一致?
<font color='red'>答案:</font>区别在于 RedisTemplate 存入 redis 的字符串有双引号,而 StringRedisTemplate 存入 redis 的字符串居然没有双引号。
代码如下:
结果展示如下: RedisTemplate
StringRedisTemplate
问题 6:两者的关系是 StringRedisTemplate 继承 RedisTemplate。RedisTemplate 是一个泛型类,而 StringRedisTemplate 则不是。
源码分析:
<font color='red'>先看 StringRedisTemplate:</font>
StringRedisTemplate 是继承 RedisTemplate 的,一般来说子类继承父类,应该能实现更多的功能,但是此处我们发现 StringRedisTemplate 继承的是 RedisTemplate 的泛型类,指定了 String-String 的泛型!故功能只专注于 String 类型!
这下就一目了然了!
<font color='red'>再看 RedisTemplate:</font>
问题 7:为啥 RedisTemplate 需要自定义序列化?
<font color='red'>答案:</font>RedisTemplate 可以接收任意的 Object 作为值写入 Redis,只不过写入前会把 Object 序列化为字节形式,默认采用 JDK 序列化。但是这种方式有两个缺点:
可读性差。对键值对进行了序列化,中文字符串序列化后的内容表示为 16 进制表示的数据,可读性差。
内存空间占用大。存储了额外的对象的类型信息,占用了内存空间。因此,RedisTemplate 需要自定义序列化方式
问题 8:对 redis 的 value 使用序列化方式有几种?
<font color='red'>答案:4 种:字符串序列化、json 序列化、jdk 序列化 JdkSerializationRedisSerializer、StringRedisSerializer、GenericJackson2JsonRedisSerializer、GenericFastJsonRedisSerializer。</font>其中:StringRedisSerializer =》 字符串序列化 JdkSerializationRedisSerializer =》 jdk 序列化 GenericJackson2JsonRedisSerializer 和 GenericFastJsonRedisSerializer =》 json 序列化







评论