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+insert
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            /**
             * 将目标对象的类名、方法名和参数数组拼接起来作为键的生成规则,以确保缓存的唯一性
             */
            @Override
            public 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;//主键ID
    private 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 {

    @Autowired
    private BookRepository bookRepository;

    /**
     * @Cacheable根据方法参数将方法结果保存到缓存中,在后续使用相同参数调用方法时,
     * 会直接返回缓存中的值,而不再调用目标方法
     */
    @Cacheable
    public 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 {

    @Autowired
    private BookService bookService;

    @PostMapping
    public 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();
    }

    @PutMapping
    public String updateBook(@RequestBody Book book){
        Book resultBook = bookService.updateBook(book);
        return resultBook.toString();
    }

    @DeleteMapping
    public 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.mfbz.cn/a/660092.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无人港口/码头兴起,可视化大屏功不可没。

码头/港口可视化大屏可以为管理上带来多方面的价值&#xff0c;包括但不限于&#xff1a; 1. 实时监控&#xff1a; 大屏可以将港口的各种数据、设备状态、船舶位置等信息实时展示&#xff0c;管理人员可以通过大屏随时监控港口的运营情况&#xff0c;及时发现并处理问题。 2…

第13章 常用类

一、包装类 二、String String的常用方法&#xff1a; equals&#xff1a;判断内容是否相等&#xff0c;区分大小写。 String str1 "hello";String str2 "Hello";System.out.println(str1.equals(str2));//false equalsIgnoreCase&#xff1a;判断内容…

清华大学提出IFT对齐算法,打破SFT与RLHF局限性

监督微调&#xff08;Supervised Fine-Tuning, SFT&#xff09;和基于人类反馈的强化学习&#xff08;Reinforcement Learning from Human Feedback, RLHF&#xff09;是预训练后提升语言模型能力的两大基础流程&#xff0c;其目标是使模型更贴近人类的偏好和需求。 考虑到监督…

一文看懂标准版和Pro版的区别

在CRMEB的众多产品中&#xff0c;有这样两款产品经常被拿来比较&#xff0c;它们就是CRMEB的标准版和Pro版商城系统&#xff0c;今天&#xff0c;我们就来盘一下这两款系统之间究竟有哪些不同。 1、Pro版系统性能更卓越 CRMEB Pro版采用Tp6 SwooleRedis高性能框架开发&#…

游戏联运平台如何助力游戏行业飞速发展?

随着科技的进步和互联网的普及&#xff0c;游戏行业正以前所未有的速度飞速发展。在这个过程中&#xff0c;游戏联运平台凭借其独特的优势和功能&#xff0c;成为了推动游戏行业腾飞的关键力量。本文将探讨游戏联运平台如何助力游戏行业实现飞速发展。 一、游戏联运平台的定义与…

四川易点慧电商抖音小店信誉之店

在当下这个电商飞速发展的时代&#xff0c;如何在众多网店中挑选出一家既可靠又值得信赖的店铺&#xff0c;成为了消费者们关注的焦点。四川易点慧电子商务有限公司抖音小店以其卓越的品质和诚信的经营&#xff0c;逐渐在抖音平台上崭露头角&#xff0c;成为了众多消费者心中的…

北京大学第一医院与智源研究院共同发布基于可信执行环境的AI医学影像挑战赛

肾动脉狭窄是导致继发性高血压及肾功能不全的常见原因&#xff0c;而目前针对肾动脉狭窄功能学的评估尚处于探索阶段。数据保护和可信计算环境是目前人工智能技术应用于临床研究的一大瓶颈。北京大学第一医院与北京智源人工智能研究院心脏AI 联合研究中心特发布基于可信执行环境…

FreeSwitch视频会议同时支持内网和外网接入

我们在使用freeswitch进行视频会议时&#xff0c;之前所有的用户都是通过外网的方式接入&#xff0c;因为fs给其返回的sdp协议内容里&#xff0c;只需要fs配置的外网IP就可以了&#xff1b;最近由于引入新的业务需要有其他内网的服务器也可以直接接入fs的视频会议房间&#xff…

VirtualBox虚拟机与bhyve虚拟机冲突问题解决@FreeBSD

问题 在安装完bhyve虚拟系统的主机上启动VirtualBox虚拟机的时候&#xff0c;报错&#xff1a;不能为虚拟电脑 debian 打开一个新任务. VirtualBox cant operate in VMX root mode. Please close all other virtualization programs. (VERR_VMX_IN_VMX_ROOT_MODE). 返回 代码…

5292A 物联网信号分析仪

5292A 物联网信号分析仪 —— 10MHz&#xff5e;6GHz —— 简述 5292A物联网信号分析仪是一款通用的矢量信号分析仪&#xff0c;频率范围覆盖 10MHz&#xff5e;6GHz&#xff0c;具有良好的频率、功率测量精度和稳定度&#xff1b;支持模拟与数字调制信号、全制式的通信标准…

Linux DHCP server 配置

参考&#xff1a;linux dhcp配置多vlan ip_linux 接口vlan-CSDN博客 配置静态IP地址&#xff1a; 给固定的MAC地址分配指定的IP地址&#xff0c;固定的IP地址不必包含在指定的IP池中&#xff0c;如果包含在IP地址池中&#xff0c;固定的IP地址会从IP地址池中移除 配置方法&…

数组-检查数组内是否存在和为7的倍数的子序列

一、题目描述 二、解题思路 这里首先要分辨清楚是子序列还是子数组 原数组&#xff1a;[1,2,3,4,5] 子序列&#xff1a;元素和元素之间相对位置保持不变&#xff0c;但是在原数组中不一定连续&#xff0c;如&#xff1a;[1,3,4]&#xff1b; 子数组&#xff1a;元素元素之间保…

小型水库水雨情和大坝安全监测解决方案

小型水库水雨情和大坝安全监测解决方案 小型水库作为重要的水资源管理和防洪调蓄设施&#xff0c;在保障农业灌溉、居民饮水及防洪安全方面发挥着不可或缺的作用。然而&#xff0c;由于其规模限制&#xff0c;小型水库往往在水雨情监测和大坝安全评估方面面临资源和技术的双重…

全球市值最高的能源公司沙特阿美股份拟出售,筹集百亿美元

KlipC报道&#xff1a;据5月28日市场消息&#xff0c;沙特政府可能最快会在本周宣布拟出售国营石油公司沙特阿美股份&#xff0c;筹集100亿-200亿美元。 沙特阿美是世界最大的石油生产商&#xff0c;2019年在沙特证交所上市。沙特的经济高度依赖石油出口。此前&#xff0c;受石…

DxO PhotoLab 6 for Mac/Win:专业RAW图片编辑的利器

DxO PhotoLab 6 for Mac/Win是一款专为摄影师和摄影爱好者打造的专业RAW图片编辑软件&#xff0c;它将先进的技术、丰富的功能与直观的操作完美结合&#xff0c;为用户提供了一款全面而强大的图片处理工具。 一、技术领先&#xff0c;处理RAW图片更高效 DxO PhotoLab 6采用了…

Swift 构造过程

构造过程 一、存储属性的初始赋值1、构造器2、默认属性值 二、自定义构造过程1、形参的构造过程2、形参命名和实参标签3、不带实参标签的构造器形参4、可选属性类型5、构造过程中常量属性的赋值 三、默认构造器结构体的逐一成员构造器 四、值类型的构造器代理五、类的继承和构造…

[MySQL最详细的知识点]

MySQL 关系型数据库以一行作为一个记录,列数据库以一列为一个记录一行是一个记录,一列是一个字段一行是一个实体,一列是一个属性 MySQL引擎: MySQL引擎&#xff1a;可以理解为&#xff0c;MySQL的“文件系统”&#xff0c;只不过功能更加强大。​MySQL引擎功能&#xff1a;除…

小白跟做江科大32单片机之蜂鸣器

1.复制之前编写的工程库项目&#xff0c;详细工程库创建过程如下链接&#xff1a; 小白跟做江科大32单片机之LED闪烁-CSDN博客https://blog.csdn.net/weixin_58051657/article/details/139295351?spm1001.2014.3001.55022.按照江科大老师给的图片进行连接蜂鸣器 3.修改main.c…

【Unity之FGUI】白仙章Fairy GUI控件详解二

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;就业…

数字人如何赋能农产业智慧化发展?

在第八届中国荔枝龙眼产业大会上&#xff0c;推出了AI数字人宣传大使“荔枝妹”&#xff0c;数字人“荔枝妹”不仅可以在现场犹如真人般与观众、嘉宾实时互动交流&#xff0c;又可以作为AI交互数字人&#xff0c;具有情感交互、语音互动等能力&#xff0c;用户可以通过与AI交互…