下面我就开始介绍springboot中的缓存:

首先了解下JSR107、Spring缓存抽象等等概念。

一 JSR107(下面会有具体Springboot代码演示)

Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry。
1 CachingProvider定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期访问多个CachingProvider。

2 CacheManager定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。

3 Cache是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。

4 Entry是一个存储在Cache中的key-value对.

5 Expiry 每一个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。

如下图所示:

二 Spring缓存抽象(下面会有具体Springboot代码演示)

Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化我们开发;
1 Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;

2 Cache接口下Spring提供了各种xxxCache的实现,如RedisCache,EhCacheCache , ConcurrentMapCache等;每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果返回给用户。下次直接从缓存中获取。

3 使用Spring缓存抽象时我们需要关注以下两点;

第一点就是确定方法需要被缓存以及他们的缓存策略 ,第二点就是从缓存中读取之前缓存存储的数据,如下图所示:

了解jdbc的朋友就会很清楚,这就跟面向jdbc编程是一个道理,统一一个规范,统一面向jdbc编程。

三 缓存注解(下面会有具体Springboot代码演示)

同样支持spel表达式

四 缓存使用(下面会有具体Springboot代码演示)

要在Springboot中使用缓存需要以下几步:

第一步: 导入spring-boot-starter-cache模块

第二步: @EnableCaching开启缓存

第三步: 使用缓存注解

下面开始演示代码: 先说明一下我使用的是IntelliJ IDEA,这是一个非常不错的软件,用过eclipse的人再来用IDEA会有不一样的感觉,当然IDEA需要的内存要求会高些。有需要的朋友可以去官网下载,IDEA(https://www.jetbrains.com/idea/)是 JetBrains 公司的产品, 公司旗下还有其他产品,比如:WebStorm:用于开发 JavaScript、 HTML5、 CSS3 等前端技术; Android Studio:用于开发android(google 基于 IDEA 社区版进行迭代); PhpStorm; RubyMine; PyCharm; AppCode:用于开发 OC/Swift; CLion:用于开发 C/C++等。

1 首先在pom.xml文件中引入坐标地址

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-cache</artifactId>
  4. </dependency>

我们从图中可以看到cache这个模块导入进来了。

2 在主程序中开启缓存注解

@SpringBootApplication
@EnableCaching
public class Springboot07CacheApplication {

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

3 开始测试代码,首先做好准备

javaBean如下:

package com.lxj.cache.bean;
import java.io.Serializable;
public class Employee  implements Serializable{
private Integer id;private String lastName;private String email;private Integer gender; //性别 1男  0女private Integer dId;public Employee() {}
public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) {
super();this.id = id;this.lastName = lastName;this.email = email;this.gender = gender;this.dId = dId;}
public Integer getId() {
return id;}
public void setId(Integer id) {
this.id = id;}
public String getLastName() {
return lastName;}
public void setLastName(String lastName) {
this.lastName = lastName;}
public String getEmail() {
return email;}
public void setEmail(String email) {
this.email = email;}
public Integer getGender() {
return gender;}
public void setGender(Integer gender) {
this.gender = gender;}
public Integer getdId() {
return dId;}
public void setdId(Integer dId) {
this.dId = dId;}
@Overridepublic String toString() {
return “Employee [id=” + id + “, lastName=” + lastName + “, email=” + email + “, gender=” + gender + “, dId=”+ dId + “]”;}
}

controller层如下:


@RestController
public class EmployeeController {
<span style="color:#bbb529;">@Autowired

EmployService employService;
@GetMapping("/emp/{id}")
public Employee getEmpById(@PathVariable(“id”) Integer id) {
Employee empById = employService.getEmpById(id);
return empById;
}
}service层如下:

@CacheConfig(cacheNames = “emp”)
@Service
public class EmployService {
<span style="color:#bbb529;">@Autowired

EmploeeMapper emploeeMapper;

@Cacheable(cacheNames = {“emp”})
public Employee getEmpById(Integer id){
System.out.println(“查询” + id + “号员工”);
Employee employee = emploeeMapper.getEmpById(id);
return employee;
}
}

mapper接口如下:

@Mapper
public interface EmploeeMapper {
@Select(“SELECT * FROM employee WHERE id = #{id}”)
public Employee getEmpById(Integer id);@Update(“UPDATE employee SET lastName=#{lastName},email=#{email},gender=#{gender},d_id=#{dId} WHERE id = #{id}”)
public  void updateEmpById(Employee employee);@Delete(“DELETE * FROM employee WHERE id = #{id}”)
public void deleteEmpById(Integer id);

@Insert(“INSERT INTO employee(lastName,email,gender,d_id) VALUES(#{lastName},#{email},#{gender},#{dId})”)
public  void InsertEmp(Employee employee);

@Select(“SELECT * FROM employee WHERE lastName = #{lastName}”)
public Employee getEmpByLastName(String lastName);
}

application.properties如下:

spring.datasource.username=root
spring.datasource.password=xxxxx
spring.datasource.url=jdbc:mysql://localhost:3306/springCache
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

#开启驼峰命名法
mybatis.configuration.map-underscore-to-camel-case=true

#打印sql语句日志
logging.level.com.lxj.cache.mappers=debug

#控制台打印配置信息
debug=true

sql语句如下:

  1. DROP TABLE IF EXISTS employee;
  2. CREATE TABLE employee (
  3. id int(11) NOT NULL AUTO_INCREMENT,
  4. lastName varchar(255) DEFAULT NULL,
  5. email varchar(255) DEFAULT NULL,
  6. gender int(2) DEFAULT NULL,
  7. d_id int(11) DEFAULT NULL,
  8. PRIMARY KEY (id)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

整个工程结构:

4 测试

运行项目,打开浏览器输入 http://localhost:8080/emp/1 ,可以看到浏览器返回的值

再来看看IEDA的控制台打印情况

可以看到第一次获取数据是从数据库中获取的,再次输入 http://localhost:8080/emp/1

可以看到并没有查询数据库,而是从缓存中获取的数据,这说明缓存起作用了,下面来分析下标记缓存的方法:

@Cacheable(cacheNames = {“emp”})
public Employee getEmpById(Integer id){
System.out.println(“查询” + id + “号员工”);Employee employee = emploeeMapper.getEmpById(id);return  employee;
}

@Cacheables  能够根据方法的请求参数对其结果进行缓存

cacheNames 缓存的名称,也就是在缓存中有一个叫emp的名字来标识不同的缓存组件。

其他的参数在文章上面有介绍,详细介绍请看上文,下面看看@CachePut的功能。

service有如下方法:

//    @CachePut: 既调用方法,又更新缓存数据;同步更新缓存
//    修改了数据库的某个数据,同时更新缓存
//    运行:
//        1.先调用目标方法
//        2.将目标方法的结果缓存起来

@CachePut(key = “#result.id”)
public Employee updateEmp(Employee employee){
System.out.println(“updateEmp “+employee);emploeeMapper.updateEmpById(employee);return  employee;}

controller如下:

@GetMapping(”/emp”)
public Employee updateEmp(Employee employee){
Employee emp = employService.updateEmp(employee);return  emp;
}

我们更新id=1的员工 信息,返回了更新后的值

这个时候我再查询id=1的员工

看看控制台打印情况,可以看到只有之前更新时打印的数据,并没有从数据库查数据

下面看看@CacheEvict

//       @CacheEvict:缓存清除
//       key:指定要清除的数据
//       allEntries = true : 指定清除这个缓存中的所有数据
//       beforeInvocation=fales: 缓存的清除是否在方法之前执行
//       默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除
//       beforeInvocation=true  代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除

@CacheEvict(beforeInvocation = true)
public void deleteEmp(Integer id){
System.out.println(“delteEmp: " + id);int i = 101/0;emploeeMapper.deleteEmpById(id);}
@GetMapping(”/delEmp")
public  String deleteEmp(Integer id){
employService.deleteEmp(id);return “success”;
}

首先从浏览器输入 http://localhost:8080/emp/1  ,将1号员工进行缓存

可以看到已经缓存1号员工,接着输入 http://localhost:8080/delEmp?id=1 将1号员工删除

这里有异常是因为有一句int i = 101/0 所以异常,但是不影响结果,这里主要是测试添加的参数,如下

然后再来查询1号员工

可以看到缓存被清除,重新从数据库中获取缓存。

五 总结

关于这篇博客就到这里,这是关于SpringBoot缓存的基本用法,有什么问题可以提出来,在下一篇文章,博主会讲讲关于SpringBoot中Cache的原理,会进行源码Debug,希望对大家有用。

SpringBoot与缓存使用及原理(上)相关推荐

  1. springboot中缓存技术的使用、原理及其运行流程

    Springboot中缓存的工作原理 要想在springboot中使用缓存,首先要了解springboot中缓存的工作原理. 我们知道springboot在启动时会有很多的自动配置类(xxx-Auto ...

  2. syslog 向内存中缓存_动画:深入浅出从根上理解 HTTP 缓存机制及原理!

    HTTP 缓存,对于前端的性能优化方面来讲,是非常关键的,从缓存中读取数据和直接向服务器请求数据,完全就是一个在天上,一个在地下. 我们最熟悉的是 HTTP 服务器响应返回状态码 304,304 代表 ...

  3. SpringBoot SimpleCacheConfiguration的自动配置原理

    引言   在之前的博客中分享了简单的SpringBoot缓存的HelloWorld程序,在篇博客中主要来分析一下SpringBoot对于缓存自动配置的原理 缓存自动配置原理   首先在SpringBo ...

  4. SpringBoot @Cacheable缓存入门程序

    导语 在之前的博客中分享了关于SpringBoot缓存的一些基本的概念,在这篇博客中提供一个小小的入门的实例,通过这个实例可以更好的了解关于SpringBoot缓存有关的知识点.   首先既然是缓存的 ...

  5. SpringBoot之缓存篇

    SpringBoot与缓存 ​ 随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一.Spring ...

  6. 第十七课:js数据缓存系统的原理

    这一章主要讲的是jQuery的缓存系统的历史发展,以及他自己的框架的缓存系统的实现.都是源码解析. 我就挑几个重点讲下: (1)jQuery的缓存机制的原理 jQuery的缓存机制实现的原理是在元素中 ...

  7. java+cache使用方法_JVM代码缓存区CodeCache原理及用法解析

    一. CodeCache简介 从字面意思理解就是代码缓存区,它缓存的是JIT(Just in Time)编译器编译的代码,简言之codeCache是存放JIT生成的机器码(native code).当 ...

  8. 【SpringBoot整合缓存】-----spring-boot-starter-cache篇

    本专栏将从基础开始,循序渐进,以实战为线索,逐步深入SpringBoot相关知识相关知识,打造完整的SpringBoot学习步骤,提升工程化编码能力和思维能力,写出高质量代码.希望大家都能够从中有所收 ...

  9. MinIO入门-02 SpringBoot 整合MinIO并实现文件上传

    SpringBoot 整合MinIO并实现文件上传 1.依赖 <!-- https://mvnrepository.com/artifact/io.minio/minio --> < ...

  10. 《深入分布式缓存:从原理到实践》

    喔家ArchiSelf 入行20多年来,有了一次不同寻常的尝试,虽然只是合力出了一本书. 时间回溯到2016年, 最初出于挖人的险恶用心,进入了一个名叫"中生代技术"的技术群.本以 ...

最新文章

  1. MySQL数据库时间类型datetime、bigint、timestamp的查询效率比较
  2. Android事件机制
  3. 廖雪峰js教程笔记 2
  4. 通过Iframe在A网站页面内嵌入空白页面的方式,跨域获取B网站的数据返回给A网站!...
  5. excel模糊匹配两列文字_Excel快速画出美观饼图
  6. UVa 10375 - Choose and divide(唯一分解定理)
  7. 实验吧Web-易-天网管理系统(php弱类型,==号)
  8. 搭一个简单的接口测试框架
  9. docker commit 制作镜像
  10. Spring中使用JdbcTemplate和HibernateTemplate的数据库操作
  11. arm 升腾310_简单说说华为海思的芯片产品线
  12. 3项目估算表_浮动油封生产项目可行性研究报告
  13. 安卓中为什么onkeydown没有相应_为什么今年在园区注册个人独资企业能将企业总税率降低至3%?...
  14. Lintcode--007(不同的子序列)
  15. 网上鞋店html,“鞋店”是“shoes store”还是“shoe store”?
  16. QT5 配置nPcap过程
  17. 小知识 定位测绘领域中全站仪/接收机RTK精度1cm+1ppm的含义
  18. 记一次前端优化首屏加载
  19. 面试题:如何测试微信朋友圈
  20. python期中考试试卷分析_最新期中考试试卷分析与反思

热门文章

  1. JVM内存大小配置方式
  2. JAVA语言基础-反射、特性
  3. Linux01-BASH脚本编程之信号捕捉及任务计划53
  4. delphi中的Format函数详解
  5. 5.数据中台 --- 数据汇聚联通:打破企业数据孤岛
  6. 4.Jenkins 权威指南 --- 自动化测试
  7. 10.Linux 高性能服务器编程 --- 信号
  8. 6.高性能MySQL --- 查询性能优化(1)
  9. 30. SELinux
  10. 121. VLD 的使用