SpringBoot与Spring Framework提供的缓存抽象

目录

缓存

项目总结

新建一个SpringBoot项目

pom.xml

application.properties

CacheConfig

Book

BookRepository接口

BookService服务类

BookController控制器

SpringbootCacheApplication启动类

启动项目,使用Postman测试


参考博文:

  • 1、使用到了JPA,建议先看看SpringBoot整合JPA保存数据:http://t.csdnimg.cn/zJfHv

缓存

  • Spring Boot 实际上是建立在 Spring Framework 的基础之上的,并且提供了对 Spring Framework 中各种功能的自动化配置和简化,包括缓存抽象。

  • Spring Framework 提供了一套强大的缓存抽象,包括 @Cacheable@CachePut@CacheEvict 等注解,以及 CacheManager 接口和相关的实现类,用于管理缓存的操作和配置。这些缓存抽象使得开发人员可以方便地在应用程序中集成各种缓存解决方案,并使用统一的方式来进行缓存操作。

  • 缓存机制:Spring的缓存抽象是作用于方法级别的,在每次调用一个目标方法时,缓存抽象都会应用一个缓存行为来检查是否已经为给定参数调用了该方法。如果已经调用该方法,则返回缓存的结果,而不会再调用实际的方法;如果还没有调用该方法,则会调用目标方法,并将方法返回的结果缓存,同时向用户返回该结果。这种缓存机制适用于对给定参数始终返回相同结果的方法
  • 缓存抽象提供了5个缓存注解:
@Cacheable根据方法参数将方法结果保存到缓存中
@CachePut执行方法,同时更新缓存 
@CacheEvict清空缓存 
@Caching重新组合要应用于某个方法的多个缓存操作
@CacheConfig在类级别共享一些共同的缓存相关配置

项目总结

  • 引入依赖
  • 在 application.properties 或 application.yml 中配置数据库连接,所选缓存提供商的相关信息
  • 在 Spring Boot 应用程序的主类上,添加 @EnableCaching 注解来启用缓存支持
  • 在需要进行缓存的方法上添加 @Cacheable@CachePut@CacheEvict 等注解,来控制缓存的行为。

新建一个SpringBoot项目

引入依赖:

  • Lombok
  • Spring Web
  • Spring Data JPA
  • MySQL Driver
  • Spring Cache Abstraction

项目结构:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.study</groupId><artifactId>springboot_cache</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot_cache</name><description>Demo project for Spring Boot</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.32</version><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

application.properties

# test为数据库名
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# Hibernate配置属性,设置自动根据实体类创建,更新和验证数据库表结构
spring.jpa.properties.hibernate.hbm2ddl.auto=update
# Hibernate 将会使用 MySQL 5 InnoDB 存储引擎的方言来生成针对 MySQL 数据库的 SQL 查询和语句。
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
# 将运行期生成的SQL语句输出到日志以供调试
spring.jpa.show-sql=true

CacheConfig

  • 因为缓存本质上是键-值存储,所以每次调用缓存的方法都需要转换成合适的键来进行缓存访问。
  • 默认的键生成策略:
    • 如果缓存方法没有参数,则使用SimpleKey.EMPTY作为键
    • 如果有多个参数,则返回包含所有参数的SimpleKey
package com.study.springboot_cache.config;import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.lang.reflect.Method;
import java.util.Arrays;/*** 这是一个自定义的缓存键生成器(KeyGenerator)配置类。* 在这个配置类中,你重写了 CachingConfigurerSupport 类的 keyGenerator() 方法,* 用于生成缓存的键,避免出现重复的键。*/
@Configuration
public class CacheConfig extends CachingConfigurerSupport {@Bean@Override //alt+insertpublic KeyGenerator keyGenerator() {return new KeyGenerator() {/*** 将目标对象的类名、方法名和参数数组拼接起来作为键的生成规则,以确保缓存的唯一性*/@Overridepublic Object generate(Object target, Method method, Object... objects) {StringBuilder sb = new StringBuilder();sb.append(target.getClass().getName()).append(".").append(method.getName()).append(Arrays.toString(objects));return sb.toString();}};}
}

Book

package com.study.springboot_cache.entity;import lombok.Data;
import lombok.ToString;import javax.persistence.*;
import java.time.LocalDate;@Data
@ToString
@Entity
@Table(name = "books")
public class Book {//主键自动增长@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;//主键IDprivate String title;//书名private String author;//作者private String bookConcern;//出版社private LocalDate publishDate;//出版日期private Float price;//价格
}

BookRepository接口

  • JpaRepository 接口:是 Spring Data JPA 提供的一个泛型接口,用于简化数据访问层的开发。它提供了许多内置的方法,用于对实体类进行常见的 CRUD 操作
package com.study.springboot_cache.repository;import com.study.springboot_cache.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;public interface BookRepository extends JpaRepository<Book,Integer> {Book getById(Integer id);
}

BookService服务类

  • 对于DAO类来说,通常是一个方法完成一次SQL访问操作,粒度比较细,对于一次前端请求来说,可能需要调用多个DAO类方法来得到结果,而服务层就是负责组合这些DAO方法的,因此,在服务层的类方法缓存结果是比较合适的
  • SpEL(Spring Expression Language,Spring表达式语言),可以通过SpEL来选择合适的参数生成键
package com.study.springboot_cache.service;import com.study.springboot_cache.entity.Book;
import com.study.springboot_cache.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;/*** @CacheConfig(cacheNames = "book")在类级别共享一些共同的缓存相关配置* 设置缓存的名称为book*/
@Service
@CacheConfig(cacheNames = "book")
public class BookService {@Autowiredprivate BookRepository bookRepository;/*** @Cacheable根据方法参数将方法结果保存到缓存中,在后续使用相同参数调用方法时,* 会直接返回缓存中的值,而不再调用目标方法*/@Cacheablepublic Book getBookById(Integer id){System.out.println("getBookById: "+id);return bookRepository.getById(id);}/*** @CachePut(key = "#result.id")调用方法以更新缓存* key = "#result.id": 缓存的key,其值为SpEL表达式*/@CachePut(key = "#result.id")public Book saveBook(Book book){System.out.println("saveBook: "+book);book = bookRepository.save(book);return book;}@CachePut(key = "#result.id")public Book updateBook(Book book){System.out.println("updateBook: "+book);book = bookRepository.save(book);return book;}/*** @CacheEvict(beforeInvocation = true)删除缓存中过时或未使用的数据* beforeInvocation = true: 在方法执行前删除*/@CacheEvict(beforeInvocation = true)public void deleteBook(Integer id){System.out.println("deleteBook: "+id);bookRepository.deleteById(id);}
}

BookController控制器

package com.study.springboot_cache.controller;import com.study.springboot_cache.entity.Book;
import com.study.springboot_cache.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/book")
public class BookController {@Autowiredprivate BookService bookService;@PostMappingpublic String saveBook(@RequestBody Book book){Book resultBook = bookService.saveBook(book);return resultBook.toString();}@GetMapping("/{id}")public String getBookById(@PathVariable Integer id){Book resultBook = bookService.getBookById(id);return resultBook.toString();}@PutMappingpublic String updateBook(@RequestBody Book book){Book resultBook = bookService.updateBook(book);return resultBook.toString();}@DeleteMappingpublic String deleteBook(@PathVariable Integer id){bookService.deleteBook(id);return "删除成功!";}
}

SpringbootCacheApplication启动类

package com.study.springboot_cache;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication
@EnableCaching //启用缓存
public class SpringbootCacheApplication {public static void main(String[] args) {SpringApplication.run(SpringbootCacheApplication.class, args);}}

启动项目,使用Postman测试

1、向表中添加数据

2、查询数据

第一次查询时,会调用方法,在控制台打印出SQL语句;

第二次使用相同参数查询时,使用缓存中的数据,不会调用方法,控制台没有输出

3、 更改数据

更改数据,再查询两次,第二次查询也是使用缓存中数据,不调用方法,控制台不打印SQL语句

 

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

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

相关文章

llvm 3.5 源码分析 clang for x86 001 之搭环境

0&#xff0c;目标 编译 针对x86 的&#xff0c;debug 的 c语言的编译器 1&#xff0c;下载代码 git clone --recursive 。。。llvm-project.git $ cd llvm-project 2&#xff0c;预备代码 llvm 3.5 版本的源代码&#xff0c;早期版本&#xff0c;可能比较小比较容易debug $…

Python知识点1---变量和数据类型

提前说一点&#xff1a;如果你是专注于Python开发&#xff0c;那么本系列知识点只是带你入个门再详细的开发点就要去看其他资料了&#xff0c;而如果你和作者一样只是操作其他技术的Python API那就足够了。 在所有知识开始前&#xff0c;先给大家介绍一下Python的注释&#xf…

使用STM32和TB6600驱动器控制42BYGH步进电机

项目概述 1. 系统组成 STM32微控制器&#xff1a;作为主控制器&#xff0c;负责发出控制指令。TB6600驱动器&#xff1a;用于接收STM32的指令并驱动步进电机。42BYGH步进电机&#xff1a;作为执行元件&#xff0c;根据控制信号进行转动。电源&#xff1a;为STM32、TB6600和步…

Unity MiniCPM-V 让引擎拥有视觉

Unity MiniCPM-V 让引擎拥有视觉 前言项目Python环境布置Unity场景布置代码编写添加并设置脚本总结 鸣谢AI提示 前言 新发布的MiniCPM-V&#xff0c;忍不住玩一下&#xff0c;可以让之前制作的语音助手拥有一定的视觉能力&#xff08;不是OpenCV不行&#xff0c;而是AI更加符合…

深入理解Java关系运算符,避免常见错误!

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

Java Web是前端吗:深入解析Java Web技术的定位与边界

Java Web是前端吗&#xff1a;深入解析Java Web技术的定位与边界 在探讨Java Web是否属于前端领域时&#xff0c;我们首先需要明确Java Web技术的定位和它所涉及的范畴。本文将从四个方面、五个方面、六个方面和七个方面来深入解析这一问题&#xff0c;带您领略Java Web技术的…

复现CELL文章图片,在线绘制scRNA-seq多个cluster的差异火山图

导读 火山图表示两组间的差异&#xff0c;而在scRNA-seq中&#xff0c;同时会有多个cluster&#xff08;vs其他cluster&#xff09;的差异。如果用常规火山图展示&#xff0c;可能需要绘制十几个图。有没有更高效的展示方法呢&#xff1f;今天给大家带来CELL文章“A Spatiotem…

linux pigz 多线程压缩解压

压缩&#xff1a; tar --use-compress-programpigz -cvpf abc.tgz ./abc 解压&#xff1a; tar --use-compress-programpigz -xvf ./abc.tgz 解压到指定位置&#xff1a;tar --use-compress-programpigz -xvf ./abc.tgz -C ./hhh

原生js访问http获取数据的方法

在原生JavaScript中&#xff0c;直接通过浏览器端的JavaScript访问HTTP接口获取数据通常涉及XMLHttpRequest对象或现代的fetch API。 1. 使用XMLHttpRequest XMLHttpRequest是一个老旧的API&#xff0c;但在某些情况下仍然很有用。以下是一个简单的例子&#xff1a; javascr…

打造SimPO新算法,微调8B模型超越Claude 3 Opus

前言 大型语言模型&#xff08;LLM&#xff09;近年来取得了巨大进展&#xff0c;但要将其与人类价值观和意图相一致&#xff0c;使其变得有用、诚实和无害&#xff0c;仍然是一个挑战。强化学习从人类反馈中&#xff08;RLHF&#xff09;是一种常用的方法&#xff0c;通过微调…

Charles的安装和web端抓包配置

1.Charles的安装 通过官网下载&#xff1a;https://www.charlesproxy.com/download/&#xff0c;我之前下载的是4.6.2版本&#xff0c;下载成功后点击安装包&#xff0c;点击下一步下一步即可安装成功。 ​​ ​ 安装成功后打开charles页面如下所示。 ​ 2.乱码问题解决 打开…

【C++】STL:栈和队列模拟实现

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

绘画参数配置及使用

绘画参数配置及使用 路径&#xff1a;站点后台-功能-AI绘画 进入参数配置 接口选择&#xff1a;多种接口自主选择&#xff08;需自己准备key&#xff09;&#xff0c;对应接口的key对话和绘画通用 存储空间&#xff1a; 位置在超管后台-存储空间 自主选择存储&#xff08;需…

【数据结构与算法】七大排序算法(下)

【数据结构与算法】七大排序算法(下) &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;数据结构与算法&#x1f345; &#x1f33c;文章目录&#x1f33c; 2.3 交换排序 2.3.1 冒泡排序 2.3.2 快速排序 2.3.3 快速排序(非递归) 2.4 归并…

fpga入门 串口定时1秒发送1字节

一、 程序说明 FPGA通过串口定时发送数据&#xff0c;每秒发送1字节&#xff0c;数据不断自增 参考小梅哥教程 二、 uart_tx.v timescale 1ns / 1psmodule uart_tx(input wire sclk,input wire rst_n,output reg uart_tx);parameter …

Spring bean加载顺序

最近在开发过程中遇到一个Spring bean加载顺序的问题&#xff0c;容器在启动的时候 会通过InitializingBean 的afterPropertiesSet 加载两级缓存&#xff0c;但是加载的过程中因为没有将load的容器对象加载到Spring 容器中导致NPE &#xff0c;所以今天来巩固一下spring bean的…

【Python Cookbook】S01E12 根据字段将记录分组

目录 问题解决方案讨论 问题 如果有一系列的字典或对象实例&#xff0c;我们想根据某个特定的字段来分组迭代数据。 解决方案 假设有如下字典列表&#xff1a; rows [{address: 5412 N CLARK, date: 07/01/2012},{address: 5148 N CLARK, date: 07/04/2012},{address: 580…

W25Q64CV SPI Flash Memory

SPI简介 SPI是一种同步串行通信接口规范&#xff0c;用于短距离通信&#xff0c;主要应用于嵌入式系统。SPI通信由一个主设备和一个或多个从设备组成&#xff0c;其中主设备生成时钟信号并控制通信的开始和结束。 SPI通信的基本组成 四个基本信号 SCK (Serial Clock) - 时钟…

centos7下安装MySQL,Oracle数据库

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 操作系统版本为CentOS 7 使⽤ MySQ…

python数据分析——datetime数据类型2

参考资料&#xff1a;活用pandas库 # 导入pandas库 import pandas as pd # 加载数据集 teslapd.read_csv(r"...\data\tesla_stock_yahoo.csv") # 查看数据 print(tesla.head()) 1、基于日期取数据子集 # 将Date数据列转换为datetime类型 tesla[Date]pd.to_datetime…