阅读本文大概需要7分钟。
今天在项目中看到了这两个类,至于这两个类是做什么的,相信大家做开发的应该不难猜到,其实就是通过这两个类来操作Redis,不知道大家有没有用过这两个类,其实老实说我之前真的没用过,倒是在用的过程中确实出现了很多问题,今天就跟大家聊聊这两个类。
想必大家已经非常清楚,我们在项目中使用Redis肯定要通过一些类去操作从而设置或者获取一个值,操作的这个类可能是你们公司自己封装的工具类,但是也有公司没有封装工具类,是使用一些框架本身的一些类去进行操作的,更多的可能是Jedis,RedisTemplate和StringRedisTemplate这两个类可能使用的朋友比较少,也可能大家在使用了,只是我没用而已,但是不管怎么样,我们的目的都是一样的。
首先我们先来看下这两个类有什么关系,我们来看下源码
RedisTemplate类
StringRedisTemplate类
我们可以通过代码看出,StringRedisTemplate这个类是继承自RedisTemplate这个类的,虽然是这样的,但是我刚开始使用RedisTemplate往Redis中存储数据,使用StringRedisTemplate取出存储的数据时候,却是取不出来的,我就一直很纳闷,为什么会出现这样的情况,于是我连了下客户端,却发现,我存储的数据不是以可读的方式显示的。
这个是我们的代码
@GetMapping("getName") public void test() { // 使用 RedisTemplate 存储数据 redisTemplate.opsForValue().set("name","张三"); // 使用 StringRedisTemplate 获取数据 String name = stringRedisTemplate.opsForValue().get("name"); System.out.println("name : " + name); }
这是我们的结果
我刚开始有点疑惑,为什么会拿不到数据呢?结果我用RedisClient客户端直接获取我存储的值,结果还是没有拿到值。
这个时候就比较奇怪了,难道我的值没存储进去,那我使用RedisTemplate再获取一下,看能不能拿到。
@GetMapping("getName") public void test() { // 使用 RedisTemplate 存储数据 redisTemplate.opsForValue().set("name","张三"); // 使用 StringRedisTemplate 获取数据 // String name = stringRedisTemplate.opsForValue().get("name"); // 使用 RedisTemplate 获取数据 String name = (String) redisTemplate.opsForValue().get("name"); System.out.println("name : " + name); }
可以看到,我们拿到了我们设想的结果值
如果结果值可以拿到,那是不是可以说明这个值已经成功保存在Redis中了,但是我们通过StringRedisTemplate却无法获取到,我们直接在客户端通过key去获取也获取不到,那这到底是为什么呢?
我们再来看看这两个类的源码,是不是还有一些我们没发现的密码。
RedisTemplate类
StringRedisTemplate类
通过查看源码我们确实发现了问题,原来这两个类具有不同的序列化方式
RedisTemplate使用的是 :
JdkSerializationRedisSerializer
StringRedisTemplate使用的是 :
StringRedisSerializer
原来是序列化捣的鬼,我们猜想是不是我们在存储键值对的时候RedisTemplate把我们的值转换为了其他的格式,怎么查看呢?我们通过客户端来查看一下,有没有name这个key。
通过查看我们发现,根本没有name这个key,但是我们却发现存在一个不可读的key和value,是不是我们在存储的时候RedisTemplate已经帮助我们进行序列化为这种数据格式之后再存储到Redis中,其实确实是这样的,当你去通过RedisTemplate取值的时候,他会先把你的key序列化为它的数据格式,然后再去Redis中进行获取,将获取到的值再进行解析,就可以拿到我们想要的值。
既然清楚了RedisTemplate会把我们的数据序列化为我们不可读的格式,那么StringRedisTemplate又是怎么样的呢?我们再来看一看。
@GetMapping("getAge") public void test1() { // 使用 RedisTemplate 存储数据 stringRedisTemplate.opsForValue().set("age","20"); // 使用 StringRedisTemplate 获取数据 String age1 = stringRedisTemplate.opsForValue().get("age"); System.out.println("age : " + age1); // 使用 RedisTemplate 获取数据 String age2 = (String) redisTemplate.opsForValue().get("age"); System.out.println("age : " + age2); }
我们来看下结果
我们通过StringRedisTemplate获取到了我们想要的数据。我们再来看看客户端存储的数据格式是不是跟RedisTemplate是一样的。
我们发现并不是,那么大家可能要问了,那么我们究竟要在什么时候使用RedisTemplate,又在什么时候使用StringRedisTemplate呢?其实这个问题我也不好给大家太过准确的答案,毕竟我也刚用,我在网上看了很多博客,总结起来就是你在操作一个简单类型,比如说字符串这类数据的时候,可以考虑使用StringRedisTemplate,但是你要操作一些复杂的数据,比如说你要操作一个对象那么建议使用RedisTemplate。
END
更多精彩内容请关注”一个程序员的成长“
本文分享自微信公众号 - 一个程序员的成长(xiaozaibuluo)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。