七叶笔记 » 数据库 » 浅谈RedisTemplate和StringRedisTemplate的区别

浅谈RedisTemplate和StringRedisTemplate的区别

一、区别 区别点1:两者的关系是StringRedisTemplate继承RedisTemplate。RedisTemplate是一个泛型类,而StringRedisTemplate则不是。区别点2:两者序列化策略不同,StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。区别点3:(疑惑点)两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。区别点4:StringRedisTemplate只能对key=String,value=String的键值对进行操作,RedisTemplate可以对任何类型的key-value键值对操作。

二、问题总结

问题1:究竟是数据隔离?还是存入的数据访问不到?用词是否严谨?

答案:严谨说并不是数据隔离,而应该说成是彼此存入redis的数据存在,但是访问不到;而数据隔离通常指的是数据存在同一个库下,但是自己只能查看并访问自己的数据,而redis中数据都能看到且只是使用不同RedisTemplate和StringRedisTemplate对象彼此访问不到而已。

问题2:(重要)我自己测试RedisTemplate和StringRedisTemplate居然都可以彼此访问到存取的字符串值,为啥?别人文章说数据不共通

答案:所谓的彼此访问不到数据,前提是自己不重新对RedisTemplate进行序列化设置,大白话讲就是直接使用默认的,这样才能实现彼此数据隔离访问不到,而实现了序列化后RedisTemplate和StringRedisTemplate对字符串类型数据就都能获取了。

而我的能访问到就是我对RedisTemplate进行了序列化设置,比如如下代码,注意这一行: template.setKeySerializer(RedisSerializer.string());这样设置后就会导致RedisTemplate和StringRedisTemplate针对string类型的属性值使用了相同的序列化方式,这样就能彼此访问到数据了;反之不设置这一行,就会彼此反问不到数据。

问题3:.源码分析RedisTemplate和StringRedisTemplate的序列化方式

RedisTemplate的序列化

StringRedisTemplate的序列化

问题4:.RedisTemplate和StringRedisTemplate使用默认序列化方式存值区别在哪?仍然使用如下代码,只不过自己不设置序列化使用默认值

结果如下:

可以发现stringRedisTemplate存入的还是字符串样式,能直接看出属性值为def,然而RedisTemplate存入的key值前面居然多加了一串16进制的字符串值,同时存入redis的结果也是转换为字节数组bytes之后的看不懂的值。

stringRedisTemplate

RedisTemplate

问题5:.RedisTemplate和StringRedisTemplate存入redis的字符串类型不一致?

答案:区别在于RedisTemplate存入redis的字符串有双引号,而StringRedisTemplate存入redis的字符串居然没有双引号。

代码如下:

结果展示如下: RedisTemplate

StringRedisTemplate

问题6:两者的关系是StringRedisTemplate继承RedisTemplate。RedisTemplate是一个泛型类,而StringRedisTemplate则不是。

源码分析:

先看 StringRedisTemplate:

StringRedisTemplate 是继承 RedisTemplate的,一般来说子类继承父类,应该能实现更多的功能,但是此处我们发现 StringRedisTemplate 继承的是 RedisTemplate的泛型类,指定了String-String的泛型!故功能只专注于String类型!

这下就一目了然了!

再看 RedisTemplate:

问题7:为啥RedisTemplate 需要自定义序列化?

答案:RedisTemplate 可以接收任意的 Object 作为值写入 Redis,只不过写入前会把 Object 序列化为字节形式,默认采用 JDK 序列化。但是这种方式有两个缺点:

可读性差。对键值对进行了序列化,中文字符串序列化后的内容表示为 16 进制表示的数据,可读性差。内存空间占用大。存储了额外的对象的类型信息,占用了内存空间。

因此,RedisTemplate 需要自定义序列化方式

问题8:对redis的value使用序列化方式有几种?

答案:4种:字符串序列化、json序列化、jdk序列化JdkSerializationRedisSerializer、StringRedisSerializer、GenericJackson2JsonRedisSerializer、GenericFastJsonRedisSerializer。其中:StringRedisSerializer =》 字符串序列化JdkSerializationRedisSerializer =》 jdk序列化GenericJackson2JsonRedisSerializer和GenericFastJsonRedisSerializer =》 json序列化

三、案例:springboot整合redis五种数据结构API string(字符串)类型hash(哈希)类型list(列表)类型set(无序集合)类型zset(有序集合)类型

pom依赖

环境变量配置,redis采用windows的客户端启动,链接本地

User实体

1、string(字符串)类型

使用场景:key-value缓存、计数操作对象:redisTemplate.opsForValue()添加数据:set(Object k, Object v);获取数据:get(Object k);获取数据长度:size(Object k);拼接内容:append(Object k, String s);数值加一:increment(Object k);数值减一:decrement(Object k);

2、hash(哈希)类型

使用场景:缓存对象(string类型也可以实现-值存json对象字符串)操作对象:redisTemplate.opsForHash()添加数据:put(Object h, Object hk, Object hv);获取map对象某值:get(Object h, Object o);获取map对象:entries(Object h);

3、list(列表)类型

使用场景:队列、栈(左进右出:队列,左进左出:栈)操作对象:redisTemplate.opsForList()从列表左侧添加数据:leftPush(Object k, Object v);从列表左侧取数据:leftPop(Object k);从列表右侧取数据:rightPop(Object k);

4、set(无序集合)类型

使用场景:无序且不重复的集合,求交、差、并集操作对象:redisTemplate.opsForSet()获取两个集合的交集:intersect(Object k, Object k1);获取两个集合的差集:difference(Object k,Object k1);获取两个集合的并集:union(Object k,Object k1);

5、zset(有序集合)类型

使用场景:根据权重获取集合操作对象:redisTemplate.opsForZSet()添加数据:add(Object k, Object v, Object v1);根据权重范围获取集合:rangeByScore(Object k,Object v,Object v1);

6、删除key

四、总结:

当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可,但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择。

 到此这篇关于浅谈RedisTemplate和StringRedisTemplate的区别 的文章就介绍到这了,更多相关RedisTemplate和StringRedisTemplate的区别 内容请搜索七叶笔记以前的文章或继续浏览下面的相关文章希望大家以后多多支持七叶笔记!

相关文章