SpringBoot缓存管理

1、默认缓存管理

Spring框架支持透明地向应用程序添加缓存对缓存进行管理,其管理缓存的核心是将缓存应用于
操作数据的方法,从而减少操作数据的执行次数,同时不会对程序本身造成任何干扰。

Spring Boot继承了Spring框架的缓存管理功能,通过使用@EnableCaching注解开启基于注解的缓存支持,Spring Boot就可以启动缓存管理的自动化配置。

接下来针对Spring Boot支持的默认缓存管理进行讲解

 

2、基础环境搭建

2.1、准备数据

使用创建的springbootdata的数据库,该数据库有两个表t_article和t_comment

2.2、创建项目,功能编写

(1)在Dependencies依赖选择项中添加SQL模块中的JPA依赖、MySQL依赖和Web模块中的Web依赖

(2)编写数据库表对应的实体类,并使用JPA相关注解配置映射关系

package com.lagou.pojo;

import javax.persistence.*;

@Entity(name = "t_comment") // 使用这种方式,那么我么在编写原生sql语句的时候就不在需要添加,nativeQuery = true这个属性
/* @Entity
@Table(name = "t_comment") 使用这种方式配置映射实体类,当我们编写原生sql语句进行查询时,我们就必须要加上nativeQuery = true这个属性,否则会报错
*/
public class Comment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String content;
    private String author;
    @Column(name = "a_id")
    private Integer aId;

    @Override
    public String toString() {
        return "Comment{" +
                "id=" + id +
                ", content='" + content + '\'' +
                ", author='" + author + '\'' +
                ", aId=" + aId +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Integer getaId() {
        return aId;
    }

    public void setaId(Integer aId) {
        this.aId = aId;
    }
}

(3)编写数据库操作的Repository接口文件 

package com.lagou.repository;

import com.lagou.pojo.Comment;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;


public interface CommentRepository extends JpaRepository<Comment, Integer> {
    // 根据评论id修改评论作者author
    @Transactional
    @Modifying // update操作需要加上此注解
    @Query(value = "update t_comment c set c.author = ?1 where c.id=?2", nativeQuery = true)
    public int updateComment(String author, Integer id);
}

(4)编写service层

package com.lagou.service;

import com.lagou.pojo.Comment;
import com.lagou.repository.CommentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class CommentService {
    @Autowired
    private CommentRepository commentRepository;

    /**
     * @Cacheable: 将该方法查询结果comment存放在SpringBoot默认缓存中
     * cacheNames: 起一个缓存的命名空间,对应缓存的唯一标识
     * value:缓存结果   key:默认只有一个参数的情况下,key值默认就是方法参数值; 如果没有参数或者多个参数的情况:会使用SimpleKeyGenerate来为生成key
     */
    @Cacheable(cacheNames = "comment")
    public Comment findCommentById(Integer id) {
        Optional<Comment> byId = commentRepository.findById(id);
        if (byId.isPresent()) {
            Comment comment = byId.get();
            return comment;
        }
        return null;
    }
}

(5)编写Controller层

package com.lagou.controller;

import com.lagou.pojo.Comment;
import com.lagou.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CommentController {
    @Autowired
    private CommentService commentService;
    @RequestMapping(value = "/findCommentById")
    public Comment findCommentById(Integer id) {
        Comment comment = commentService.findCommentById(id);
        return comment;
    }
}

(6)编写配置文件

在项目全局配置文件application.properties中编写对应的数据库连接配置

# MySQL数据库连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
#显示使用JPA进行数据库查询的SQL语句
spring.jpa.show-sql=true
#开启驼峰命名匹配映射
mybatis.configuration.map-underscore-to-camel-case=true
#解决乱码
spring.http.encoding.force-response=true

(7)测试

上图情况,是因为没有在Spring Boot项目中开启缓存管理。在没有缓存管理的情况下,虽然数据表中的数据没有发生变化,但是每执行一次查询操作(本质是执行同样的SQL语句),都会访问一次数据库并执行一次SQL语句 

3、默认缓存体验

在前面搭建的Web应用基础上,开启Spring Boot默认支持的缓存,体验Spring Boot默认缓存的使用效果

(1)使用@EnableCaching注解开启基于注解的缓存支持

package com.lagou;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching // 开启springboot基于注解的缓存管理支持
public class SpringCacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCacheApplication.class, args);
    }

}

(2)使用@Cacheable注解对数据操作方法进行缓存管理。将@Cacheable注解标注在Service类的查询方法上,对查询结果进行缓存 

// 根据评论id查询评论信息
@Cacheable(cacheNames = "comment")
public Comment findById(int comment_id){
    Optional<Comment> optional = commentRepository.findCommentById(comment_id);
    if(optional.isPresent()){
        return optional.get();
    }
    return null;
}

上述代码中,在CommentService类中的findCommentById(int comment_id)方法上添加了查询缓存注解@Cacheable,该注解的作用是将查询结果Comment存放在Spring Boot默认缓存中名称为comment的名称空间(namespace)中,对应缓存唯一标识(即缓存数据对应的主键k)默认为方法参数comment_id的值 

(3)测试访问

可以看出,再次 执行findCommentById()方法正确查询出用户评论信息Comment,在配置了SpringBoot默认注解后,重复进行同样的查询操作,数据库只执行了一次SQL查询语句,说明项目开启的默认缓存支持已经生效 

  • 底层结构:在诸多的缓存自动配置类中, SpringBoot默认装配的是SimpleCacheConfiguration ,他使用的CacheManager 是 ConcurrentMapCacheManager, 使用 ConcurrentMap 当底层的数据结构,按照Cache的名字查询出Cache, 每一个Cache中存在多个k-v键值对,缓存值 

4、缓存注解介绍 

刚刚通过使用@EnableCaching、@Cacheable注解实现了Spring Boot默认的基于注解的缓存管理,除此之外,还有更多的缓存注解及注解属性可以配置优化缓存管理 

4.1、@EnableCaching注解

@EnableCaching是由spring框架提供的,springboot框架对该注解进行了继承,该注解需要配置在类上(在中,通常配置在项目启动类上),用于开启基于注解的缓存支持

4.2、@Cacheable注解

@Cacheable注解也是由spring框架提供的,可以作用于类或方法(通常用在数据查询方法上),用于对方法结果进行缓存存储。注解的执行顺序是,先进行缓存查询,如果为空则进行方法查询,并将结果进行缓存;如果缓存中有数据,不进行方法查询,而是直接使用缓存数据

@Cacheable注解提供了多个属性,用于对缓存存储进行相关配置

属性名说明
value/cacheNames指定缓存空间的名称,必配属性。这两个属性二选一使用
key指定缓存数据的key,默认使用方法参数值,可以使用SpEL表达式
keyGenerator指定缓存数据的key的生成器,与key属性二选一使用
cacheManager指定缓存管理器
cacheResolver指定缓存解析器,与cacheManager属性二选一使用
condition指定在符合某条件下,进行数据缓存
unless指定在符合某条件下,不进行数据缓存
sync指定是否使用异步缓存。默认false

执行流程&时机

方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取,(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建;去Cache中查找缓存的内容,使用一个key,默认就是方法的参数,如果多个参数或者没有参数,是按照某种策略生成的,默认是使用KeyGenerator生成的,使用SimpleKeyGenerator生成key,SimpleKeyGenerator生成key的默认策略:

参数个数key
没有参数new SimpleKey()
有一个参数参数值
多个参数new SimpleKey(params)

常用的SPEL表达式

描述示例
当前被调用的方法名#root.mathodName
当前被调用的方法#root.mathod
当前被调用的目标对象#root.target
当前被调用的目标对象类#root.targetClass
当前被调用的方法的参数列表#root.args[0] 第一个参数, #root.args[1] 第二个参数...
根据参数名字取出值#参数名, 也可以使用 #p0 #a0 0是参数的下标索引
当前方法的返回值#result

4.3、@CachePut注解

目标方法执行完之后生效, @CachePut被使用于修改操作比较多,哪怕缓存中已经存在目标值了,但是这个注解保证这个方法依然会执行,执行之后的结果被保存在缓存中

@CachePut注解也提供了多个属性,这些属性与@Cacheable注解的属性完全相同。

更新操作,前端会把id+实体传递到后端使用,我们就直接指定方法的返回值从新存进缓存时的key="#id" , 如果前端只是给了实体,我们就使用key="#实体.id" 获取key. 同时,他的执行时机是目标方法结束后执行, 所以也可以使用 key="#result.id" , 拿出返回值的id

4.4、@CacheEvict注解 

@CacheEvict注解是由Spring框架提供的,可以作用于类或方法(通常用在数据删除方法上),该注解的作用是删除缓存数据。@CacheEvict注解的默认执行顺序是,先进行方法调用,然后将缓存进行清除。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SpringBoot提供了方便的缓存支持,可以通过添加相关注解和依赖来启用和配置缓存功能。 要启用缓存功能,可以在主程序入口上添加@EnableCaching注解。例如,在SpringBoot应用的主类上添加@EnableCaching注解可以启用缓存功能。同时,还可以添加其他注解,如@SpringBootApplication、@EnableTransactionManagement等。以下是一个示例代码: ```java @SpringBootApplication @EnableTransactionManagement @EnableCaching public class SpringbootMabatisDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringbootMabatisDemoApplication.class, args); } } ``` 此外,还需要在项目的pom.xml文件中添加缓存启动器的依赖项。例如,可以添加以下依赖项来导入Spring Boot缓存启动器: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> ``` 通过添加这个依赖项,可以使用Spring Boot提供的缓存功能。 此外,Spring Boot还提供了org.springframework.cache.CacheManager接口来统一不同的缓存技术,并支持使用JCache(JSR-107)等标准缓存技术。这个接口可以帮助你在应用中管理和配置缓存。 总结起来,Spring Boot提供了简便的缓存支持,你可以通过添加@EnableCaching注解来启用缓存功能,同时在pom.xml文件中添加缓存启动器的依赖项。还可以使用org.springframework.cache.CacheManager接口来管理和配置缓存。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Springboot缓存](https://blog.csdn.net/AALouisaa/article/details/126450883)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悠然予夏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值