Spring Cache 简介

在 Spring 3.1 中引入了多 Cache 的支持,在 spring-context 包中定义了org.springframework.cache.Cacheorg.springframework.cache.CacheManager 两个接口来统一不同的缓存技术。Cache 接口包含缓存的常用操作:增加、删除、读取等。CacheManager 是 Spring 各种缓存的抽象接口。

Spring 支持的常用 CacheManager 如下:

CacheManager 描述
SimpleCacheManager 使用简单的 Collection 来存储缓存
ConcurrentMapCacheManager 使用 java.util.ConcurrentHashMap 来实现缓存
NoOpCacheManager 仅测试用,不会实际存储缓存
EhCacheCacheManger 使用EhCache作为缓存技术。EhCache 是一个纯 Java 的进程内缓存框架,特点快速、精干,是 Hibernate 中默认的 CacheProvider,也是 Java 领域应用最为广泛的缓存
JCacheCacheManager 支持JCache(JSR-107)标准的实现作为缓存技术
CaffeineCacheManager 使用 Caffeine 作为缓存技术。用于取代 Guava 缓存技术。
RedisCacheManager 使用Redis作为缓存技术
HazelcastCacheManager 使用Hazelcast作为缓存技术
CompositeCacheManager 用于组合 CacheManager,可以从多个 CacheManager 中轮询得到相应的缓存

Spring Cache 提供了 @Cacheable 、@CachePut 、@CacheEvict 、@Caching 等注解,在方法上使用。通过注解 Cache 可以实现类似事务一样、缓存逻辑透明的应用到我们的业务代码上,且只需要更少的代码。

核心思想:当我们调用一个方法时会把该方法的参数和返回结果最为一个键值对存放在缓存中,等下次利用同样的参数来调用该方法时将不会再执行,而是直接从缓存中获取结果进行返回。

Cache注解

1.@EnableCaching

开启缓存功能,一般放在启动类上。

2.@CacheConfig

当我们需要缓存的地方越来越多,你可以使用@CacheConfig(cacheNames = {"cacheName"})注解在 class 之上来统一指定value的值,这时可省略value,如果你在你的方法依旧写上了value,那么依然以方法的value值为准。

3.@Cacheable

根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上

查看源码,属性值如下:

属性/方法名 解释
value 缓存名,必填,它指定了你的缓存存放在哪块命名空间
cacheNames 与 value 差不多,二选一即可
key 可选属性,可以使用 SpEL 标签自定义缓存的key
keyGenerator key的生成器。key/keyGenerator二选一使用
cacheManager 指定缓存管理器
cacheResolver 指定获取解析器
condition 条件符合则缓存
unless 条件符合则不缓存
sync 是否使用异步模式,默认为false

4.@CachePut

使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上

查看源码,属性值如下:

属性/方法名 解释
value 缓存名,必填,它指定了你的缓存存放在哪块命名空间
cacheNames 与 value 差不多,二选一即可
key 可选属性,可以使用 SpEL 标签自定义缓存的key
keyGenerator key的生成器。key/keyGenerator二选一使用
cacheManager 指定缓存管理器
cacheResolver 指定获取解析器
condition 条件符合则缓存
unless 条件符合则不缓存

5.@CacheEvict

使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上

查看源码,属性值如下:

属性/方法名 解释
value 缓存名,必填,它指定了你的缓存存放在哪块命名空间
cacheNames 与 value 差不多,二选一即可
key 可选属性,可以使用 SpEL 标签自定义缓存的key
keyGenerator key的生成器。key/keyGenerator二选一使用
cacheManager 指定缓存管理器
cacheResolver 指定获取解析器
condition 条件符合则缓存
allEntries 是否清空所有缓存,默认为 false。如果指定为 true,则方法调用后将立即清空所有的缓存
beforeInvocation 是否在方法执行前就清空,默认为 false。如果指定为 true,则在方法执行前就会清空缓存

6.@Caching

该注解可以实现同一个方法上同时使用多种注解。可从其源码看出:

public @interface Caching {

	Cacheable[] cacheable() default {};

	CachePut[] put() default {};

	CacheEvict[] evict() default {};

}

Spring Cache 使用

1.构建项目,添加依赖

<?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.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.zwqh</groupId>
<artifactId>spring-boot-cache</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-cache</name>
<description>spring-boot-cache</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Cache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency> <!-- 热部署模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
</dependency> <!-- mysql 数据库驱动. -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency> <!-- mybaits -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

2.application.properties 配置文件

#datasource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=UTF-8&useSSL=true
spring.datasource.username=root
spring.datasource.password=123456
#mybatis
mybatis.mapper-locations=classpath:/mapper/*Mapper.xml

3.实体类

public class UserEntity implements Serializable{

	/**
*
*/
private static final long serialVersionUID = 5237730257103305078L;
private Long id;
private String userName;
private String userSex;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserSex() {
return userSex;
}
public void setUserSex(String userSex) {
this.userSex = userSex;
} }

4.数据层 dao 和 mapper.xml

public interface UserDao {
//mapper.xml方式
/**
* 获取所有用户
* @return
*/
List<UserEntity> getAll();
/**
* 根据id获取用户
* @return
*/
UserEntity getOne(Long id);
/**
* 新增用户
* @param user
*/
void insertUser(UserEntity user);
/**
* 修改用户
* @param user
*/
void updateUser(UserEntity user);
/**
* 删除用户
* @param id
*/
void deleteUser(Long id); }
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zwqh.springboot.dao.UserDao">
<resultMap type="cn.zwqh.springboot.model.UserEntity" id="user">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userSex" column="user_sex"/>
</resultMap>
<!-- 获取所有用户 -->
<select id="getAll" resultMap="user">
select * from t_user
</select>
<!-- 根据用户ID获取用户 -->
<select id="getOne" resultMap="user">
select * from t_user where id=#{id}
</select>
<!-- 新增用户 -->
<insert id="insertUser" parameterType="cn.zwqh.springboot.model.UserEntity">
insert into t_user (user_name,user_sex) values(#{userName},#{userSex})
</insert>
<!-- 修改用户 -->
<update id="updateUser" parameterType="cn.zwqh.springboot.model.UserEntity">
update t_user set user_name=#{userName},user_sex=#{userSex} where id=#{id}
</update>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="Long">
delete from t_user where id=#{id}
</delete>
</mapper>

5.业务代码层接口 Service 和实现类 ServiceImpl

public interface UserService {

	/**
* 查找所有
* @return
*/
List<UserEntity> getAll();
/**
* 根据id获取用户
* @param id
* @return
*/
UserEntity getOne(Long id);
/**
* 新增用户
* @param user
*/
void insertUser(UserEntity user);
/**
* 修改用户
* @param user
*/
void updateUser(UserEntity user); void deleteAll1(); void deleteAll12();
}
@Service
@CacheConfig(cacheNames = {"userCache"})
public class UserServiceImpl implements UserService { @Autowired
private UserDao userDao; @Override
@Cacheable("userList") // 标志读取缓存操作,如果缓存不存在,则调用目标方法,并将结果放入缓存
public List<UserEntity> getAll() {
System.out.println("缓存不存在,执行方法");
return userDao.getAll();
} @Override
@Cacheable(cacheNames = { "user" }, key = "#id")//如果缓存存在,直接读取缓存值;如果缓存不存在,则调用目标方法,并将结果放入缓存
public UserEntity getOne(Long id) {
System.out.println("缓存不存在,执行方法");
return userDao.getOne(id);
} @Override
@CachePut(cacheNames = { "user" }, key = "#user.id")//写入缓存,key为user.id,一般该注解标注在新增方法上
public void insertUser(UserEntity user) {
System.out.println("写入缓存");
userDao.insertUser(user);
} @Override
@CacheEvict(cacheNames = { "user" }, key = "#user.id")//根据key清除缓存,一般该注解标注在修改和删除方法上
public void updateUser(UserEntity user) {
System.out.println("清除缓存");
userDao.updateUser(user);
} @Override
@CacheEvict(value="userCache",allEntries=true)//方法调用后清空所有缓存
public void deleteAll1() { } @Override
@CacheEvict(value="userCache",beforeInvocation=true)//方法调用前清空所有缓存
public void deleteAll2() { } }

6.测试 Controller

@RestController
@RequestMapping("/user")
public class UserController { @Autowired
private UserService userService; /**
* 查找所有
* @return
*/
@RequestMapping("/getAll")
public List<UserEntity> getAll(){
return userService.getAll();
}
/**
* 根据id获取用户
* @return
*/
@RequestMapping("/getOne")
public UserEntity getOne(Long id){
return userService.getOne(id);
}
/**
* 新增用户
* @param user
* @return
*/
@RequestMapping("/insertUser")
public String insertUser(UserEntity user) {
userService.insertUser(user);
return "insert success";
}
/**
* 修改用户
* @param user
* @return
*/
@RequestMapping("/updateUser")
public String updateUser(UserEntity user) {
userService.updateUser(user);
return "update success";
}
}

7.启动 Cache 功能

@SpringBootApplication
@MapperScan("cn.zwqh.springboot.dao")
@EnableCaching //启动 Cache 功能
public class SpringBootCacheApplication { public static void main(String[] args) {
SpringApplication.run(SpringBootCacheApplication.class, args);
} }

8.数据库及测试数据

数据库和测试数据仍旧用之前的。

9.测试

编写单元测试,或者通过访问 http://127.0.0.1:8080/user/ 加上对应路径和参数。

文档

org.springframework.cache

示例代码

github

码云

非特殊说明,本文版权归 朝雾轻寒 所有,转载请注明出处.

原文标题:Spring Boot 2.X(七):Spring Cache 使用

原文地址:https://www.zwqh.top/article/info/13

如果文章对您有帮助,请扫码关注下我的公众号,文章持续更新中...

Spring Boot 2.X(七):Spring Cache 使用的更多相关文章

  1. Spring Boot 2 (三):Spring Boot 2 相关开源软件

    Spring Boot 2 (三):Spring Boot 2 相关开源软件 一.awesome-spring-boot Spring Boot 中文索引,这是一个专门收集 Spring Boot 相 ...

  2. Spring Boot(十五):spring boot+jpa+thymeleaf增删改查示例

    Spring Boot(十五):spring boot+jpa+thymeleaf增删改查示例 一.快速上手 1,配置文件 (1)pom包配置 pom包里面添加jpa和thymeleaf的相关包引用 ...

  3. Spring Boot(十四):spring boot整合shiro-登录认证和权限管理

    Spring Boot(十四):spring boot整合shiro-登录认证和权限管理 使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉 ...

  4. Spring Boot 项目学习 (三) Spring Boot + Redis 搭建

    0 引言 本文主要介绍 Spring Boot 中 Redis 的配置和基本使用. 1 配置 Redis 1. 修改pom.xml,添加Redis依赖 <!-- Spring Boot Redi ...

  5. 【自学Spring Boot】什么是Spring Boot

    为啥要有Spring Boot? 以前大学刚开始学java web的时候,需要搭建起web框架,当时使用的是SSH(struts+spring+hibernate),那就开始搭建吧,初学者哪里知道整套 ...

  6. spring boot rest 接口集成 spring security(2) - JWT配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  7. spring boot rest 接口集成 spring security(1) - 最简配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  8. [转]Spring Boot——2分钟构建spring web mvc REST风格HelloWorld

    Spring Boot——2分钟构建spring web mvc REST风格HelloWorld http://projects.spring.io/spring-boot/ http://spri ...

  9. Spring Boot (五)Spring Data JPA 操作 MySQL 8

    一.Spring Data JPA 介绍 JPA(Java Persistence API)Java持久化API,是 Java 持久化的标准规范,Hibernate是持久化规范的技术实现,而Sprin ...

随机推荐

  1. 洛谷 P4206 [NOI2005]聪聪与可可 题解

    题面 输入 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行,每 ...

  2. 【Offer】[39] 【数组中出现次数超过一半的数字】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数 ...

  3. 【LeetCode】[0001] 【两数之和】

    题目描述 思路分析 Java代码 代码链接 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整数,并返回他们的数组下标.你可以假设每种输入只会对 ...

  4. 【Offer】[4] 【二维数组中的查找】

    题目描述 思路分析 Java代码 代码链接 题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数 ...

  5. pandas可视化:各种图的简单使用

    一.Matplotlib中几种图的名字 折线图:plot 柱形图:bar 直方图:hist 箱线图:box 密度图:kde 面积图:area 散点图:scatter 散点图矩阵:scatter_mat ...

  6. vue-cli3.0 Typescript 项目集成环信WebIM 群组聊天

    项目背景 环信webim 官方没有vue版本的,自己就根据sdk重写了个vue版本的,只实现了基础的 登录 群组功能,其他的可以根据需要参考官方文档,添加相应的功能. 环信webim SDK相关文档: ...

  7. CCPC桂林

    在得知我们队伍前往桂林参加CPPC区域赛后,我是非常激动的,因为我们网络赛并没有得到名额,如果不是新都赠予我们名额,我们都没有出去打比赛的机会,同时,我们也不想浪费这个名额,我们也想打出成绩来,于是我 ...

  8. H2 数据库使用简介

    博客地址:http://www.moonxy.com 一.前言 H2 是一个用 Java 开发的嵌入式数据库,它本身只是一个类库,即只有一个 jar 文件,可以直接嵌入到应用项目中.H2 主要有如下三 ...

  9. charles 高亮Hosts

    本文参考:charles 高亮Hosts Focus Host是焦点域名的:这里配置好的可以在结构视图中,单独拎出来显示: 如下图,在把zhubangbang.com设为焦点域名,在视图中是下图这么展 ...

  10. Micrometer 快速入门

    Micrometer为最流行的监控系统提供了一个简单的仪表客户端外观,允许仪表化JVM应用,而无需关心是哪个供应商提供的指标.它的作用和SLF4J类似,只不过它关注的不是Logging(日志),而是a ...