redis 无法存储Java对象的两种解决方案

Heaven helps those who help themselves
资深码农 + 深耕理财 = 财富自由
欢迎关注

redis 无法存储 Java 对象的两种解决方案

Created by Marydon on 2020-12-12 18:26

1. 情景展示

  由上一篇,我们了解到 redis 不能直接存储 Java 对象,这对于我们 Java 语言是非常非常不友好的,因为我们经常进行数据的操作是通过对象来完成的。如何解决这个痛点问题? 

2. 方案一:序列化与反序列化

  因为 Redis 只能支持六种数据类型(string/hash/list/set/zset/hyperloglog)的操作,导致我们无法直接将对象直接存入 Redis 内存中,所以在需要 Redis 存储的六中数据类型与 Java 对象之间进行转换;

  最常见的一种替代方案就是:通过序列化和反序列化来实现,即:

  我们可以把对象序列化之后存入 Redis 缓存中,然后在取出的时候又通过转换器,将序列化之后的对象反序列化回对象,这样就完成了我们的要求。

  序列化和反序列化听不懂?用大白话翻译一下:

  序列化:将 Java 对象转成 json 字符串;反序列化:将 json 字符串转 Java 对象。

  通过这种方式,来达到曲线救国的目的。

  具体代码,我这里没有,因为这种方式我是不推荐使用的,理由是:太复杂,而且序列化和反序列化自己手动来封装的话,也容易出问题!!!

  对于 redis 缓存的操作,还是通过注入 StringRedisTemplate 来完成。

3. 方案二:spring 注解

  弃用通过 StringRedisTemplate 的方式操作 redis,改用原生注解 @CachePut,@Cacheable,@CacheEvict 来操作 redis;

  可能你不知道,使用 spring 自带的缓存也是可以实现 Java 对象的存取,下篇文章会详解介绍;

  事实上,经过实际测试发现:通过这三个原生的缓存注解,足以化解 redis 不能存储 Java 对象的尴尬,一起来看一下:

  前提:开启 spring 缓存

1
@EnableCaching

  要想使用 spring 缓存,就必须先开启缓存:在 springboot 启动项目的 Java 类加上此注解。

  关于返回值是 map,而不是 Java 对像的说明:

  这里,我已经用红框进行了标注,我再次用的是 Map,而没用 Java 实体类,并不是博主睁着眼睛说瞎话,而是我懒得改了,你把这里换成实体类,同样会被存进 redis 中的;

  不信自己可以试试,或在下篇文章也能找到答案,一起来看 redis 的存储数据结果:

  上面的 x** 代表的是中文字符。

  下一步:怎么证明二次请求是从缓存中读取的数据,而不是从数据库获取的呢?

  双管齐下:

  在从数据库获取数据的地方加个断点

  (我现在就是以 debug 模式启动的,这是一个好习惯,方便在想要调试的时候,不用再以 debug 模式重启项目)

  这是第一次执行方法后输出的 SQL 语句(这也就证明了当时 redis 里是没有这个 key 的)

  清空控制台日志记录,此时,我们再从前端发送一次请求,我们会发现:

  既没有走断点,控制台也没有 SQL 输出。

  这样,就证明了:数据是从 redis 缓存中拿到的。 

  至此,就证明了通过 spring 原生缓存注解就能够完成 Java 对象与 redis 存储数据之间的自由转化。 

  哪种方案更加方便,相信大家都得出了结论。这篇文章到此也就结束啦。

  你可能会说:@CachePut 和 @CacheEvict 还没有讲呢,我想说的是:这三个原生的 spring 缓存原生注解,其实和 redis 没有任何关系,脱离了 redis 照样可以使用;

  反倒是 redis 依赖它们三个,对于我们开发来说将会方便许多;

  所以,我单处写了一篇文章,讲解了它们三个如何完成对缓存库的增删改查,见文末推荐。

 

写在最后

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

 相关推荐:

 

与君共勉:最实用的自律是攒钱,最养眼的自律是健身,最健康的自律是早睡,最改变气质的自律是看书,最好的自律是经济独立 。

您的一个点赞,一句留言,一次打赏,就是博主创作的动力源泉!

↓↓↓↓↓↓写的不错,对你有帮助?赏博主一口饭吧↓↓↓↓↓↓