Spring Boot进阶(47):Spring Boot之集成Cache缓存 | 超级详细,建议收藏

news2024/11/22 22:06:30

1. 前言

        今天,我们来聊聊缓存这个话题。身为开发者肯定都知道,程序的瓶颈绝大体现在于数据库方面,而内存读取远远快于硬盘,当并发上升到一定高度,一次又一次的重复请求数据导致大量时间耗费在数据库查询上,性能极具恶化扛不住高并发崩了,而突破这种数据库瓶颈往往离不开它--缓存。

2. Spring对缓存的支持

        说到缓存,spring早起也对它有所深入,其中org.springframework.cache.CacheManager 和 org.springframework.cache.Cache,其二就是它所提供的缓存技术。其中对于CacheManager 是Spring 提供的各种缓存技术的抽象接口,而Cache接口则是用于包含了缓存的各种操作,而增加,删除,获取缓存等,一般不会直接和Cache接口交涉。

        接下来我就给大家具体讲解一下CacheManager,因为我们要使用到它来实现数据缓存。

3. CacheManager

spring支持的CacheManager,针对不同的缓存技术,它实现了不同的CacheManager,具体如下:

 而且,在你使用上述任意一个CacheManager,你都要注册实现CacheManager 的 Bean,具体如下:

@Bean
public EhCacheCacheManager cacheManager(CacheManager 
 ehCacheCacheManager){
    return new  EhCacheCacheManager(ehCacheCacheManager);
}

虽然有诸多不同的缓存技术,但是你配置CacheManager 必不可少。

4. 声明式缓存注解

spring提供了4种注解来声明缓存规则,具体如下:

  • @Cacheable

作用:在方法执行前 Spring 先查看缓存中是否有数据,若有,则直接返回缓存数据:若无数据,则调用方法将方法返回值放入缓存中。

  • @CachePut

作用:无论怎样,都会将方法的返回值放到缓存中

  • @CacheEvict

作用:将一条或多条数据从缓存中删除.

  • @Caching

作用:可以通过 @Caching 注解组合多个注解策略在一个方法上.

注意:对于这三个注解@Cacheable、@CachePut、@CacheEvict 都带有 key、value 属性,其中key指定的是数据在缓存中存储的键,value是只要使用的缓存名称;

例如:

//缓存key为id的数据到缓存user中
@Cacheable(value = "user",key = "#id")

//缓存新增的或更新的数据到缓存,其中缓存名称为user数据的key是user的 id
@CachePut(value = "user",key = "#user.id")

//从缓存user中删除key为id的数据
@CacheEvict(value = "user")

5. 开启声明式缓存

开启声明式缓存支持很简单,只需要在配置类上添加@EnabelCaching注解即可。例如:

@Configuration
@EnableCaching
public class CacheConfig{
    //
}

6. SpringBoot 的支持

        在 SpringBoot的广度使用上,它也很好的为大家使用带来方便,springboot项目想使用缓存技术你只需要在项目中导入cache的依赖包即可,并在配置类中使用 @EnableCaching 来开启缓存支持,如此你就可以正常使用cache缓存了,具体实例演示及项目集成我将重点放在下期来为大家讲解,这里就不做过多的赘述啦,有想法的小伙伴可以看我下篇。

7. 实例演示

如下演示一下SpringBoot项目如何集成并使用cache吧,请大家认真仔细观看。

7.1 pom添加依赖

在你的项目中找到pom.xml,添加cache的依赖包

<!-- cache 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

7.2 开启缓存功能

在你的项目启动类上添加@EnableCaching注解,这样你就无需在跟以往一样还得在xml中配置cache manager了。

@SpringBootApplication
@Configuration
@MapperScan("com.example.demo.dao")// 扫描mybatis的映射器
@EnableCaching // 开启缓存功能
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

或者你直接配置个缓存配置类,开启缓存也行。

@Configuration
@EnableCaching//启用缓存
public class CacheConfig {
}

        当你在配置类(@Configuration)上使用@EnableCaching注解时,会触发一个post processor,这会扫描每一个spring bean,查看是否已经存在注解对应的缓存。如果找到了,就会自动创建一个代理拦截方法调用,使用缓存的bean执行处理。

        记得项目集成cache时,如果你是集成过redis,请将redis的依赖先移除,否则默认会先连接redis的CacheManager 。

7.3 实战模拟

7.3.1 创建一个user实体

创建一个User实体类,封装用户信息。

/**
 * 用户基本信息实体
 */
@TableName("user")
@Data
public class UserEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO) //表示该id为自增,新增时候不需要手动设置id。
    private Integer id;

    @TableField(value = "name")
    private String name;

    @TableField(value = "age")
    private Integer age;

    @TableField(value = "sex")
    private String sex;

    @TableField(value = "address")
    private String address;

    @TableField(value = "describes")
    private String describes;

    @TableField(value = "image")
    private String image;
}

7.3.2 定义UserService接口

/**
 * 用户管理业务层接口
 */
public interface UserService extends IService<UserEntity> {
    /**
     * 新增用户
     */
    UserEntity saveUser(UserEntity user);

    /**
     * 查询缓存用户
     */
    UserEntity findUserById(Integer id);

    /**
     * 根据用户id删除用户缓存数据
     */
    void deleteUserById(Integer id);
}

7.3.3 实现UserServiceImpl类

如下:

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {

    /**
     * 新增用户
     */
    @CachePut(value = "user1",key = "#user.id")
    @Override
    public UserEntity saveUser(UserEntity user) {
        this.save(user);
        log.info("为key(id)为{}的数据做了缓存", user.getId());
        return user;
    }

    /**
     * 查询缓存用户
     */
    @Cacheable(value = "user",key = "#id")
    @Override
    public UserEntity findUserById(Integer id) {
        UserEntity user = this.getById(id);
        log.info("为key(id)为{}的数据做了缓存", user.getId());
        return user;
    }

    /**
     * 根据用户id删除用户缓存数据
     */
    @CacheEvict(value = "user")
    @Override
    public void deleteUserById(Integer id) {
//        this.removeById(id);
        log.info("删除了key(id)为{}的数据缓存", id);
    }

}

7.3.4 创建Controller接口方法

@RestController
@RequestMapping("/cache")
@Api(tags = "测试用户缓存模块", description = "测试用户缓存模块")
public class CacheController {

    @Autowired
    private UserService userService;

    /**
     * 新增用户
     */
    @PostMapping("/save-user")
    @ApiOperation(value = "新增用户", notes = "新增用户")
    public ResultResponse<UserEntity> saveUser(@RequestBody UserEntity user) {
        return new ResultResponse<>(userService.saveUser(user));
    }

    /**
     * 根据用户id查询用户信息
     */
    @GetMapping("/get-user-by-id")
    @ApiOperation(value = "根据用户id查询用户信息", notes = "根据用户id查询用户信息")
    public ResultResponse<UserEntity> findUserById(@RequestParam("id") Integer id) {
        return new ResultResponse<>(userService.findUserById(id));
    }

    /**
     * 根据用户id删除缓存用户信息
     */
    @GetMapping("/delete-user-by-id")
    @ApiOperation(value = "根据用户id删除缓存用户信息", notes = "根据用户id删除缓存用户信息")
    public void deleteUserById(@RequestParam("id") Integer id) {
        userService.deleteUserById(id);
    }

7.4 swagger在线接口文档测试

7.4.1  测试【缓存数据】添加

我们首先调用添加接口在swagger中执行,往数据库中添加一条数据。

查看一下控制台,发现成功打印插入sql且Updates=1。

7.4.2 测试查询缓存数据

然后我们再测试一下查询接口方法。

 查看一下控制台,成功打印select查询语句并成功打印出为key=59的数据已做缓存。

        随后我们多次请求id=59的这条数据,发现控制台不再打印sql,但数据又成功返回,这说明缓存生效了而不是重复请求数据库返回数据。

7.4.3 验证数据是否缓存

        接着我们执行把该id=59的数据缓存清除,然后再执行查询id=59的数据,验证是否会重新执行select查询语句且重新把数据写入缓存呢?我们拭目以待。

我们先执行请求,把id=59的缓存进行删除

 可以看到控制台输出已经删除了。

 接着我们执行一次查询接口。可以看到控制台执行了查询sql请求了数据库。

        我们再执行一次执行一次查询接口,发现控制台并无sql打印,这就证明数据是来自于缓存,而不是每次都重新查询。

... ...

        ok,我们利用Spring Cache的注解,在Spring Boot中实现了缓存功能,你会发现这种缓存的实现其实是很简单的,你学会了吗?

8. 热文推荐🔥

滴~如下推荐【Spring Boot 进阶篇】的学习大纲,请小伙伴们注意查收。

Spring Boot进阶(01):Spring Boot 集成 Redis,实现缓存自由

Spring Boot进阶(02):使用Validation进行参数校验

Spring Boot进阶(03):如何使用MyBatis-Plus实现字段的自动填充

Spring Boot进阶(04):如何使用MyBatis-Plus快速实现自定义sql分页

Spring Boot进阶(05):Spring Boot 整合RabbitMq,实现消息队列服务

Spring Boot进阶(06):Windows10系统搭建 RabbitMq Server 服务端

Spring Boot进阶(07):集成EasyPoi,实现Excel/Word的导入导出

Spring Boot进阶(08):集成EasyPoi,实现Excel/Word携带图片导出

Spring Boot进阶(09):集成EasyPoi,实现Excel文件多sheet导入导出

Spring Boot进阶(10):集成EasyPoi,实现Excel模板导出成PDF文件

Spring Boot进阶(11):Spring Boot 如何实现纯文本转成.csv格式文件?

Spring Boot进阶(12):Spring Boot 如何获取Excel sheet页的数量?

Spring Boot进阶(13):Spring Boot 如何获取@ApiModelProperty(value = “序列号“, name = “uuid“)中的value值name值?

Spring Boot进阶(14):Spring Boot 如何手动连接库并获取指定表结构?一文教会你

Spring Boot进阶(15):根据数据库连接信息指定分页查询表结构信息

Spring Boot进阶(16):Spring Boot 如何通过Redis实现手机号验证码功能?

Spring Boot进阶(17):Spring Boot如何在swagger2中配置header请求头等参数信息

Spring Boot进阶(18):SpringBoot如何使用@Scheduled创建定时任务?

Spring Boot进阶(19):Spring Boot 整合ElasticSearch

Spring Boot进阶(20):配置Jetty容器

Spring Boot进阶(21):配置Undertow容器

Spring Boot进阶(22):Tomcat与Undertow容器性能对比分析

Spring Boot进阶(23):实现文件上传

Spring Boot进阶(24):如何快速实现多文件上传?

Spring Boot进阶(25):文件上传的单元测试怎么写?

Spring Boot进阶(26):Mybatis 中 resultType、resultMap详解及实战教学

Spring Boot进阶(27):Spring Boot 整合 kafka(环境搭建+演示)

Spring Boot进阶(28):Jar包Linux后台启动部署及滚动日志查看,日志输出至实体文件保存

Spring Boot进阶(29):如何正确使用@PathVariable,@RequestParam、@RequestBody等注解?不会我教你,结合Postman演示

Spring Boot进阶(30):@RestController和@Controller 注解使用区别,实战演示

...

9. 文末🔥

        如果想系统性的学习Spring Boot,小伙伴们直接订阅bug菌专门为大家创建的Spring Boot专栏《滚雪球学Spring Boot》从入门到精通,从无到有,从零到一!以知识点+实例+项目的学习模式由浅入深对Spring Boot框架进行学习&使用。

       我是bug菌,一名想走👣出大山改变命运的程序猿。接下来的路还很长,都等待着我们去突破、去挑战。来吧,小伙伴们,我们一起加油!未来皆可期,fighting!

关注公众号,获取最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等硬核资源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/648988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win10搭建hmailserver邮件服务器(hmailserver+phpstudy+roundcube)

环境安装&#xff1a;Mysqlhmailserverphpstudyroundcube 一、Mysql安装 官网下载链接&#xff1a;https://www.mysql.com/ zip安装包下载链接&#xff1a;https://dev.mysql.com/downloads/mysql/ 1、zip安装包安装 &#xff08;1&#xff09;下载合适版本的mysql zip包&…

LeetCode------ 相交链表

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;栏目介绍:<<刷题集>>用于记录,力扣,牛客等刷题网站上的刷…

EasyExcel 批量导出

文章目录 前言一、EasyExcel 导出封装二、食用步骤1.自定义excel样式2.导出数据 三、复杂excel导出3.1. 自定义复杂表头2. 多sheet 前言 上篇写了数据导入&#xff0c;本文补充一下EasyExcel 批量导出 包括常规excel和复杂excel 一、EasyExcel 导出封装 import com.alibaba.…

手把手教你如何解开安装UKUI的黑屏故障

手把手教你如何解开安装UKUI的黑屏故障 引子 作为一个不折腾不舒服斯基的Linuxer&#xff0c;我又开始安装配置开放欧拉操作系统了。这是国产自主安全可控的Linux发行版。欧拉发行版Linux的发起者就是干正经事的华为&#xff0c;比其它拉大旗扯虎皮的国产Linux低调务实多了。…

远程控制之原理和实战

按理来说&#xff0c;本人不该发表此类专业文章&#xff0c;鄙人零星碎片化的开发经历&#xff0c;让本人斗胆向诸位网友&#xff0c;在远控方面做一点演示说明&#xff0c;谈论一点自己的认识。 程序工程代码地址&#xff1a;点击此处下载。 程序分为两个部分&#xff0c;控…

(三)Kafka 生产者

文章目录 1. Kafka 发送消息的主要步骤2.创建 Kafka 生产者3.发送消息到 Kafka&#xff08;1&#xff09;发送并忘记&#xff08;2&#xff09;同步发送&#xff08;3&#xff09;异步发送 4.生产者配置&#xff08;1&#xff09;client.id&#xff08;2&#xff09;ack&#x…

查看P端日志操作步骤

1.登录PUTTY,这里以联调环境103.160.139.82为例。 2.登录&#xff0c;查看用户名&#xff1a;hxb或zzkpt,密码&#xff1a;用户名01动态口令。 例如hxb, sunmenglei01888888 3.进入P端日志存放目录&#xff0c; cd /home/zzkpt/logs/bcip 4.比如我要查看2023年5月5日&#xf…

索引常见问题

被问到SQL和索引优化问题&#xff0c;如何切入&#xff1f; 可以用 explain 进行分析 思考流程&#xff1a;找到哪些运行时间长浪费性能的sql&#xff0c;然后再用explain分析 慢查询日志 MySQL可以设置慢查询日志&#xff0c;当SQL执行的时间超过我们设定的时间&#xff0…

在UE中使用SVT(VirtualTexture)功能

前几年VT技术非常的火&#xff0c;这项技术主要运用在地形上&#xff0c;可以达到更高级别的精细度和更多次数的纹理混合&#xff0c;但实际非地形也可以用&#xff0c;特别是对于贴图尺寸比较大且多维度子材质比较多的模型&#xff0c;做了材质合并以及VT优化后&#xff0c;可…

二、线性神经网络

文章目录 前言一、线性回归1. 线性回归的基本元素1.1 线性模型1.2 损失函数1.3 解析解1.4 梯度下降1.5 用模型进行预测 2. 正态分布与平方损失3. 从线性回归到深度网络 二、线性回归的代码实现1. 生成数据集2. 读取数据集2.1 手动实现读取数据集2.2 简洁实现读取数据集 3. 初始…

便携补光LED化妆镜方案

近段时间&#xff0c;现代科技的衍生产品&#xff0c;智能化妆镜很受爱美女士的喜爱。为此&#xff0c;宇凡微推出无极调光的LED化妆镜方案。主控芯片采用宇凡微YF单片机&#xff0c;根据LED化妆镜方案的不同功能&#xff0c;支持定制开发。 一、LED化妆镜方案介绍 在日常过程中…

Html span标签的详细介绍

HTML &#xff1c;span&#xff1e;标签_span标签_allway2的博客-CSDN博客 一、span标签的定义及用法 在html中&#xff0c;span标签是使用来组合文档中的行内元素&#xff0c;以便使用样式来对它们进行格式化。 span标签本身并没有什么格式表现&#xff08;比如&#xff1a;换…

利用Matlab和cadence实现离散傅里叶分析(DFT)

例1&#xff1a; 采样定律&#xff0c;取100个点&#xff0c;信号频率是100HZ&#xff0c;采样频率是1000HZ&#xff0c;相当于采样十个周期&#xff0c;每个周期采样十个点。 cos&#xff08;2πT&#xff09;函数是以Ts1/fs为时间间隔对样本进行采样&#xff0c;取N个采样样…

Mini热风枪 制作过程

首先引个流吧 立创开源广场&#xff1a;https://oshwhub.com/abby_qi/mini-re-feng-qiang 哔哩哔哩&#xff1a; 实物图 然后说一下硬件的选型和图 风扇&#xff1a;3010无刷风扇 额定电压3.7V&#xff08;其实这个风扇还有其他额定电压的&#xff0c;比如9V12V&#xff0c;…

PyTorch 深度学习 || 专题九:PyTorch 全连接自编码网络的无监督学习

PyTorch 全连接自编码网络的无监督学习 文章目录 PyTorch 全连接自编码网络的无监督学习1. 数据去噪1.1 计算库和数据准备工作1.2 构建自编码网络1.3 调用主函数1.4 可视化 2. 数据的重建与降维2.1 计算模块和数据的准备2.2 自编码网络数据准备2.3 自编码网络的构建2.4 自编码网…

1.5 掌握Scala内建控制结构(一)

一、条件表达式 &#xff08;一&#xff09;语法格式 if (条件) 值1 else 值2 &#xff08;二&#xff09;执行情况 条件为真&#xff0c;结果是值1&#xff1b;条件为假&#xff0c;结果是值2。如果if和else的返回结果同为某种类型&#xff0c;那么条件表达式结果也是那种…

微信小程序开发20__第三方UI组件 ColorUI 的应用

ColorUI 有鲜艳的高饱和色彩&#xff0c; 是专注视觉的微信小程序组件库。 gitee 网址 &#xff1a;ColorUI: 鲜亮的高饱和色彩&#xff0c;专注视觉的小程序组件库 一 使用方法 在微信小程序中使用 ColorUI 需要两个步骤&#xff1a; 第一步&#xff1a; 下载源码解压…

【Linux】详解环境变量与命名行参数

目录 环境变量了解PATH什么是环境变量&#xff1f;使用环境变量系统自带环境变量示例 命名行参数argc与argvenvenviron 环境变量 了解PATH 提出问题&#xff1a; 我写的可执行程序&#xff0c;与系统的可执行程序都是可执行程序&#xff0c;那么为什么执行系统的可执行程序…

Dokcer安装---Mqtt

1、拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/synbop/emqttd:2.3.6 老版本 2、运行 docker run -it --name emq -p 18083:18083 -p 1883:1883 -p 8084:8084 -p 8883:8883 -p 8083:8083 -d registry.cn-hangzhou.aliyuncs.com/synbop/emqttd:2.3.6 –name 容器…

佩戴舒适度极好的蓝牙耳机推荐,久戴不累的蓝牙耳机分享

​听歌、刷剧、游戏&#xff0c;运动、吃饭、睡觉等&#xff0c;要说现在年轻人除了离不开手机之外&#xff0c;还有就是蓝牙耳机了&#xff01;当然&#xff0c;随着蓝牙耳机的快速发展&#xff0c;各种各样的蓝牙耳机都有&#xff0c;导致很多人不知道耳机怎么选了&#xff0…