SpringBoot

SpringBoot 开发实用篇


文章目录

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


5 整合第三方技术

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

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

springboot jetty升级_springboot jetty升级

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

springboot jetty升级_缓存_02

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

【修改配置】

springboot jetty升级_spring boot_03

把远程和本地都打开

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

springboot jetty升级_spring boot_04

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

springboot jetty升级_springboot jetty升级_05

OK

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

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

springboot jetty升级_spring boot_06

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

在实现类方法上加注解

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

springboot jetty升级_数据_07

这样就OK了

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

测试

springboot jetty升级_数据_08

可以看到查是查出来了

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

springboot jetty升级_springboot jetty升级_09

这是为什么?

看看源码

springboot jetty升级_数据_10

就在这一步

springboot jetty升级_spring boot_11

解决办法

springboot jetty升级_java_12

OK,再试一次

springboot jetty升级_缓存_13

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

springboot jetty升级_spring boot_14

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

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

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

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

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

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

springboot jetty升级_数据_15

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

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

springboot jetty升级_springboot jetty升级_16

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

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

springboot jetty升级_springboot jetty升级_17

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

springboot jetty升级_数据_18

OK, Redis 已经跑起来了

再试一次

springboot jetty升级_数据_19

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

直接看看服务器吧

springboot jetty升级_spring boot_20

没毛病。改成本地的试试

springboot jetty升级_springboot jetty升级_21

重启服务器测试

springboot jetty升级_spring boot_22

经过测试发现没问题的

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

springboot jetty升级_数据_23

这就是序列化后的东西了

现在恢复成远程

springboot jetty升级_数据_24

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

【可以做到】

@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;
}

springboot jetty升级_spring boot_25

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

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

springboot jetty升级_缓存_26

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

重启服务器,直接测试!

springboot jetty升级_java_27

这是id 为46 的

现在我把它改了

springboot jetty升级_java_28

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

springboot jetty升级_缓存_29

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

springboot jetty升级_java_30

能看出来一点点

现在执行删除操作

springboot jetty升级_缓存_31

再查它

springboot jetty升级_java_32

看看服务器

springboot jetty升级_数据_33

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

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

又一个新问题

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

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

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

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

【解决办法】

@CacheRefresh(refresh = 10)

springboot jetty升级_缓存_34

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

改成3s 直接启动服务器

springboot jetty升级_spring boot_35

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

【牛逼!!!!!】

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

springboot jetty升级_java_36

statIntervalMinutes: 1

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

直接重启服务器

springboot jetty升级_缓存_37

喵的,把刷新先关了

springboot jetty升级_java_38

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

springboot jetty升级_数据_39

做笔记溜走一分钟

springboot jetty升级_java_40

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

springboot jetty升级_数据_41

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

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

好像不怎么对

笔者先把缓存清掉

springboot jetty升级_数据_42

来5次1,3次2

springboot jetty升级_缓存_43

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

springboot jetty升级_数据_44

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

【牛逼!!!!!!】

回顾一下

  • 启用方法注解

springboot jetty升级_缓存_45

  • 使用方法注解操作缓存

springboot jetty升级_java_46

  • 使用方法注解操作缓存

springboot jetty升级_spring boot_47

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

springboot jetty升级_数据_48

  • 查看缓存统计报告

springboot jetty升级_java_49

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

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