• SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.11 jetcache 方法缓存


    SpringBoot

    【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】

    SpringBoot 开发实用篇

    5 整合第三方技术

    5.11 jetcache 方法缓存
    5.11.1 jetcache 方法缓存

    之前我们又完成了jetcache 本地缓存方案的实现

    在这里插入图片描述

    如果我现在想简单的在另一个实现类中使用缓存

    在这里插入图片描述

    比如这个,有没有简单的办法,当然

    【修改配置】

    在这里插入图片描述

    把远程和本地都打开

    先测试一下Book 的业务层 能否正常使用

    在这里插入图片描述

    应该是没问题的,再试一个查询单个

    在这里插入图片描述

    OK

    如果我们想直接在方法上加注解来实现缓存的话,还需要一个新的开关

    //jetcache 启用缓存的主开关
    @EnableCreateCacheAnnotation
    //开启方法注解缓存
    @EnableMethodCache(basePackages = "com.dingjiaxiong") //开启方法缓存
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    这两个得配合使用【就是一起】

    在实现类方法上加注解

    @Override
    @Cached(name = "book",key = "#id",expire = 3600)
    public Book getById(Integer id) {
        return bookDao.selectById(id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    这样就OK了

    重启服务器【怎么样看效果,就和我们之前一样,查第1次有MP日志,第二次没有】

    测试

    在这里插入图片描述

    可以看到查是查出来了

    但是看到一个空指针的异常,

    在这里插入图片描述

    这是为什么?

    看看源码

    在这里插入图片描述

    就在这一步

    在这里插入图片描述

    解决办法

    在这里插入图片描述

    OK,再试一次

    在这里插入图片描述

    可以看到查是查到了,但是又报了一个新的异常

    在这里插入图片描述

    这个异常我见过!实体类没有实现序列化

    但是为什么要对Book 做序列化?

    原因:在Java 中,我们以对象的形式操作数据,但是Redis 不支持直接存储Java 中的object 对象

    那怎么办?肯定是先把Java 对象转成一个能存储的“东西”,然后再放入Redis

    【内部!】用的就是序列化与反序列化

    我也知道怎么改,相信你也知道

    在这里插入图片描述

    这里完事儿后,还要修改一下配置

    # 我的值在进行encode 的时候转为Java 对象
    valueEncode: java
    # 在进行Decode 转回来的时候也转为 Java 对象
    valueDecode: java
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    保证我们的值在进去、出来的时候格式可以统一

    OK,直接重启服务器,直接测试!【这里笔者就直接上动图了,效果更明显】

    在这里插入图片描述

    看到还是报错了,第二天了,笔者没开Redis 服务器

    在这里插入图片描述

    OK, Redis 已经跑起来了

    再试一次

    在这里插入图片描述

    没毛病,只有第一次查的时候有日志

    直接看看服务器吧

    在这里插入图片描述

    没毛病。改成本地的试试

    在这里插入图片描述

    重启服务器测试

    在这里插入图片描述

    经过测试发现没问题的

    看看上一步,存入redis 的数据

    在这里插入图片描述

    这就是序列化后的东西了

    现在恢复成远程

    在这里插入图片描述

    问题来了,在第一次访问过后,之后的每一次都是从缓存中取数据,如果我是说如果,有人把缓存中的数据改掉了【比如在第二次查之前,我进行了一次更新操作】,拿出来的就和数据库查的不一样了,那咋办?

    【可以做到】

    @Override
    @Cached(name = "book_",key = "#id",expire = 3600,cacheType = CacheType.REMOTE)
    public Book getById(Integer id) {
        return bookDao.selectById(id);
    }
    
    @Override
    @CacheUpdate(name = "book_",key = "#book.id",value = "#book")
    public boolean update(Book book) {
        return bookDao.updateById(book) > 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    删除也是一样的,如果数据库都没了,缓存中还有,那也是不应该的

    @Override
    @CacheInvalidate(name = "book_",key = "#id")
    public boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    一旦我在对数据库进行 了删除操作,对应的缓存中的数据也会一并删除

    重启服务器,直接测试!

    在这里插入图片描述

    这是id 为46 的

    现在我把它改了

    在这里插入图片描述

    缓存的生命周期很长,现在我再去查,应该也是从缓存中拿

    在这里插入图片描述

    从日志中也可以看到,这次并没有调用数据层,说明缓存中的数据确实也同步修改了,当然直接看看服务器吧

    在这里插入图片描述

    能看出来一点点

    现在执行删除操作

    在这里插入图片描述

    再查它

    在这里插入图片描述

    看看服务器

    在这里插入图片描述

    这就说明,数据库里面没了,缓存中也没了【妙啊】

    现在的缓存设置不能缓存空

    又一个新问题

    假设现在我们的系统数据是这样设定的,A系统能修改这个表,B系统也能修改这个表

    这个时候就有一个问题了,如果我在A系统把数据读出来了,也放到缓存了

    这个时候B系统把数据改了【A系统没有接到通知】,这个时候的缓存数据,就和数据库中的数据对不上号了

    【要想让它同步,只能让它再去查询一次】

    【解决办法】

    @CacheRefresh(refresh = 10)
    
    • 1

    在这里插入图片描述

    这个样子写上之后,就代表着,缓存会10s 就刷新一次

    改成3s 直接启动服务器

    在这里插入图片描述

    可以看到,效果特明显,第一次查完后,每隔3秒就要去查一次,保证缓存中的数据和数据库同步

    【牛逼!!!!!】

    最后在jetcache 中有一个“统计数据”的东西可以查看

    在这里插入图片描述

    statIntervalMinutes: 1
    
    • 1

    这个的意思就是每隔1分钟,在控制台上显示一个统计数据

    直接重启服务器

    在这里插入图片描述

    喵的,把刷新先关了

    在这里插入图片描述

    笔者现在会进行5次查1,3次查2,1次查3

    在这里插入图片描述

    做笔记溜走一分钟

    在这里插入图片描述

    OK,我已经执行完了,等统计

    在这里插入图片描述

    来了,book这个空间中,我们进行的所有操作

    9次get 操作,命中了9 次,这个东西就是出统计数据,帮我们分析缓存的性能

    好像不怎么对

    笔者先把缓存清掉

    在这里插入图片描述

    来5次1,3次2

    在这里插入图片描述

    OK,每个id 的第一次都走了数据库,应该的,等统计

    在这里插入图片描述

    这下对了,一共对这个缓存空间进行了8次get 操作,5 + 3,只命中了6次,因为有两次是第一次取,缓存中没有,走的数据库

    【牛逼!!!!!!】

    回顾一下

    • 启用方法注解

    在这里插入图片描述

    • 使用方法注解操作缓存

    在这里插入图片描述

    • 使用方法注解操作缓存

    在这里插入图片描述

    • 缓存对象必须保障可序列化

    在这里插入图片描述

    • 查看缓存统计报告

    在这里插入图片描述

    5.11.2 小结
    1. jetcache方法注解使用方式

    这个时候就又有人说了,你这个只支持4种【那个时候】,而且觉得linkedhashmap 太low,没有更高端的吗?

  • 相关阅读:
    如何确定自己是否适合做程序员?
    机器学习之旅-从Python 开始
    中兴设备show命令大全
    Tsinghua:Finding Skill Neurons in Pre-trained Transformer-based Language Models
    mac下终端命令提示补全
    ucOS-II在STM32F1移植
    浅识vue的虚拟DOM和渲染器
    大数据架构师——数据湖技术(二)
    【算法 | 模拟No.4】AcWing 756. 蛇形矩阵 & AcWing 40. 顺时针打印矩阵
    几种典型的深度学习算法:(CNN、RNN、GANS、RL)
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/127975664