缓存:商品信息放到缓存中间件中,

    验证码几秒钟有效也是放在缓存中间件。

缓存规范

交互流程:

如果需要使用jRS107需要导入包:

java.cache.cache-api

JSR107提供的是接口,如果需要用那些缓存的组件,就需要加入对应的实现,

如果没有对应的实现的话,是需要自己写的。

spring里面提供了缓存抽象,

CacheAutoConfiguration 加入的自动配置类

默认加入SimpleCacheConfiguration

@Configuration(
proxyBeanMethods = false
)
@ConditionalOnMissingBean({CacheManager.class})
@Conditional({CacheCondition.class})
class SimpleCacheConfiguration {
SimpleCacheConfiguration() {
} @Bean
ConcurrentMapCacheManager cacheManager(CacheProperties cacheProperties, CacheManagerCustomizers cacheManagerCustomizers) {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
List<String> cacheNames = cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
cacheManager.setCacheNames(cacheNames);
} return (ConcurrentMapCacheManager)cacheManagerCustomizers.customize(cacheManager);
}
}

使用缓存注解的前提是:

配置文件:

spring.datasource.url=jdbc:mysql://192.168.1.102:3306/mybatis
spring.datasource.username=root
spring.datasource.password=1997
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #开启驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true logging.level.root=debug

开启debug模式可以查看更加细节的日志

加入依赖:

    <dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

创建数据库表:

CREATE TABLE `employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`lastName` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`gender` int(2) DEFAULT NULL,
`d_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

实体类:

public class Employee {

    private Integer id;
private String lastName;
private Integer gender;
private String email;
private Integer dId; public Employee() {
super();
} public Employee(Integer id, String lastName, Integer gender, String email, Integer dId) {
super();
this.id = id;
this.lastName = lastName;
this.gender = gender;
this.email = email;
this.dId = dId;
} public void setId(Integer id) {
this.id = id;
} public void setLastName(String lastName) {
this.lastName = lastName;
} public void setGender(Integer gender) {
this.gender = gender;
} public void setEmail(String email) {
this.email = email;
} public void setdId(Integer dId) {
this.dId = dId;
} public Integer getId() {
return id;
} public String getLastName() {
return lastName;
} public Integer getGender() {
return gender;
} public String getEmail() {
return email;
} public Integer getdId() {
return dId;
} @Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", gender=" + gender +
", email='" + email + '\'' +
", dId=" + dId +
'}';
}
}

mapper接口

@Mapper
public interface EmployeeMapper {
@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}")
public void updateEmp(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}")
Employee getEmpByLastName(String lastname);
}

controller层:

@RestController
public class EmplloyeeController { @Autowired
EmployeeService employeeService; @RequestMapping("/emp/{id}")
public Employee getEmployee(@PathVariable("id") Integer id){
return employeeService.getEmp(id);
} @RequestMapping("/emp")
public Employee update(Employee employee){
Employee employee1 =employeeService.updateEmp(employee);
return employee1;
} @RequestMapping("/delemp")
public String deleteEMp(Integer id){
employeeService.deleteEmp(id);
return "success";
} }

在服务层我们使用缓存注解:

先开启缓存注解@EnableCaching,,在启动类中

@Cacheable

 @Cacheable(cacheNames = "emp",keyGenerator = "myKeyGenerator")
public Employee getEmp(Integer id){
System.out.println("chanxun"+id+"员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
  @Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存
如果有就不需要执行函数
如果没有就执行函数
*/

@Cacheable运行流程:

  运行的流程:
1方法运行之前,先去查询Cache组件,安装cacheNames指定的名字获取
(CacheManager先获取相应的缓存)第一次获取缓存,回自动创建出来,以后就能用了
2去Cache中查找缓存的内容弄给,使用一个key,默认是方法的参数
key是按照某个规则生成的,默认是keyGenerator生成,默认使用simplekeyGenerator
simplekeyGenerator策略:
如果没有参数,key= new SimpleKey
如果一个:使用它
如果多个,SimpleKey(params)
3 没有查到缓存就调用目标方法
4将目标方法返回的结果,放进缓存中

@Cacheable的属性和作用:

    /**
* 将方法的允许结果进行缓存,以后如果要相同的数据,直接从缓存中获取,不用调用方法
*CacheManager 管理多个Cache组件,对缓存的真正CRUD操作是在Cache组件中,
* 每一个缓存组件有自己的唯一名字
* 几个属性:
* cacheNames/value:指定缓存组件的名字,将方法的返回结果放在哪个缓存中,数组,可自定多个缓存
* key:缓存数据使用的key,可以用它来指定,默认是使用方法参数的值 1
* 可以使用SpEl格式
* keyGenerator:key的生成器,可以自己指定key的生成器组件id
* key和keyGenerator二选一,!!可以自己指定
* CacheManager:指定缓存管理器
* condition,指定符合条件的情况菜缓存 condiction ="#id>0"id的值大于0才缓存
* unless :否定缓存,当unless指定的条件为true,返回值不会被缓存,可以获取到结果进行判断
* unless = ”#result == null“如果结果为null 不缓存
* sync:是否使用异步模式

@CachePut:

/**
* @CachePut 既调用方法,又跟新缓存数据
* 场景:修改数据库的某个数据,同时跟新缓存
* 运行实际:1先调用目标方法
* 2将目标方法的结果缓存起来
测试:
1查询1好员工,,查到的结果回放到缓存当中
存储方式:key:1 value:员工信息
2以后查询还是之前的结果
3更新1号员工http://localhost:8080/emp?id=1&lastName=quanzhiqiang&gender=2
存储方式:key:传入的对象emloyee,value: 返回的employee对象
4查询1号员工??
理论上查询的应该是更新后的员工信息
但是结果是之前的信息,原因可以看看上面的缓存存储的两种方式就知道了 解决方法, @CachePut(value = "emp" ,key = "#employee.id"),指定修改的key */

改进后:

    @CachePut(value = "emp" ,key = "#result.id")
public Employee updateEmp(Employee employee){
System.out.println("updateEmp"+employee);
employeeMapper.updateEmp(employee);
return employee;
} }
//注意:你取缓存的key和我们更新缓存的key应该一致

@CacheEvict

    /**
* @CacheEvict 缓存请除
* key:通过key来指定清楚的数据
* allEntries = true:指定清除这个缓存中的所有的数据
* beforeInvocation = false:缓存的清楚是否在方法之前执行
* 默认代表方法执行之后执行,出现异常缓存不会清除。
*/
    @CacheEvict(value = "emp",key = "#id")
public void deleteEmp(Integer id){
System.out.println("deleteEmp:"+id);
employeeMapper.deleteEmpById(id);
}

@Caching:

  可以同时定义多个缓存注解:

  

    @Caching(
cacheable = {
@Cacheable(value = "emp",key = "#lastname")
},
put = {
@CachePut(value = "emp",key = "#result.id"),
@CachePut(value = "emp",key = "#result.lastName")
}
)
public Employee getEmpByLastName(String lastname){
return employeeMapper.getEmpByLastName(lastname);
} }

@CacheConfig

/*
因为每个缓存注解都要写value =”emp"
所以我们可以通过@CacheConfig注解统一设置
*/
@CacheConfig(cacheNames = "emp") 加在类上就可以了,里面的方法的缓存注解都不需要指定缓存组件名i在

spring-boot -缓存注解的更多相关文章

  1. Spring Boot缓存注解@Cacheable、@CacheEvict、@CachePut使用

    从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...

  2. 27. Spring Boot 缓存注解详解: @Cacheable、@CachePut、 @CacheEvict、@Caching、@CacheConfig

     1.使用OGNL的命名规则来定义Key的值 @Cacheable(cacheNames = {"user"},key = "#root.methodName + '[' ...

  3. Spring boot缓存初体验

    spring boot缓存初体验 1.项目搭建 使用MySQL作为数据库,spring boot集成mybatis来操作数据库,所以在使用springboot的cache组件时,需要先搭建一个简单的s ...

  4. 3步轻松搞定Spring Boot缓存

    作者:谭朝红 前言 本次内容主要介绍基于Ehcache 3.0来快速实现Spring Boot应用程序的数据缓存功能.在Spring Boot应用程序中,我们可以通过Spring Caching来快速 ...

  5. Spring Boot常用注解总结

    Spring Boot常用注解总结 @RestController和@RequestMapping注解 @RestController注解,它继承自@Controller注解.4.0之前的版本,Spr ...

  6. Spring Boot 常用注解汇总

    一.启动注解 @SpringBootApplication @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documen ...

  7. Spring Boot缓存Ehcache

    Spring Boot 整合 Ehcache   修改 pom 文件 <!-- Spring Boot 缓存支持启动器 --> <dependency> <groupId ...

  8. 3个Spring Boot核心注解,你知道几个?

    Spring Boot 核心注解讲解 Spring Boot 最大的特点是无需 XML 配置文件,能自动扫描包路径装载并注入对象,并能做到根据 classpath 下的 jar 包自动配置. 所以 S ...

  9. Spring Boot@Component注解下的类无法@Autowired的问题

    title: Spring Boot@Component注解下的类无法@Autowired的问题 date: 2019-06-26 08:30:03 categories: Spring Boot t ...

  10. Spring boot 基于注解方式配置datasource

    Spring boot 基于注解方式配置datasource 编辑 ​ Xml配置 我们先来回顾下,使用xml配置数据源. 步骤: 先加载数据库相关配置文件; 配置数据源; 配置sqlSessionF ...

随机推荐

  1. 宿主机ping不通虚拟机,虚拟机能ping通宿主机

    最近,微信提升群里好几个小伙伴遇到了如题的问题. 问了下原因,原来是我说的把宿主机网卡ip获取方式改为自动,结果他们把宿主机上虚拟网卡的ip改为自动了. 当然,分析"宿主机ping不通虚拟机 ...

  2. ISISv4协议测试——网络测试仪实操

    文章关键词 ISIS协议:路由协议:协议测试: 一.文章简介: isis是一种与ospf很相似的网络协议(属于动态路由协议),它被应用在巨大规模网络,如运营商以及银行等.同样的它也是基于链路状态算法, ...

  3. RFC2544吞吐量测试详细步骤-信而泰Renix软件操作演示

    关键词:RFC1242:RFC2544:吞吐量:吞吐率. 吞吐量概述:吞吐量即吞吐率,这个词首先在RFC1242中被提出,是评估网络设备性能的首要指标,其定义是在设备没有丢帧的情况下的最大的转发速率, ...

  4. Clickhouse - MergeTree原理

    Clickhouse - MergeTree原理 MergeTree引擎以及隶属于MergeTree引擎族的所有引擎是Clickhouse表引擎中最重要, 最强大的引擎. MergeTree引擎族中的 ...

  5. C#基础之Foreach

    下面是Foreach的介绍. 如何让一个类可以用Foreach来遍历呢. 结论:让这个类实现IEnumerable接口. 这个类有一个public的GetEnumerator的实例方法,并且返回类型中 ...

  6. 串口通讯之rs232 c++版本

    rs232.cpp #ifndef kranfix_rs232_rs232_cc #define kranfix_rs232_rs232_cc #include "rs232.h" ...

  7. 如何在windows下成功的编译和安装python组件hyperscan

    摘要:hyperscan 是英特尔推出的一款高性能正则表达式引擎,一次接口调用可以实现多条规则与多个对象之间的匹配,可以支持多种匹配模式,块模式和流模式,它是以PCRE为原型开发,并以BSD许可证开源 ...

  8. ansible二进制部署kubernetes集群

    kubernetes版本1.21.5 需要的资源文件请自行到我的阿里云盘下载 https://www.aliyundrive.com/s/zVegF78ATDV 修改主机信息 #根据自己的主机信息自行 ...

  9. 微服务从代码到k8s部署应有尽有系列(十三、服务监控)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  10. 记一次dump文件分析历程

    一.背景 今天下午,正酣畅淋漓的搬砖,突然运维同事在群里通知,核心服务某个节点内存异常,服务假死.神经一下子紧张起来,赶紧跑到运维那边观察现象. 观察的结果是服务内存溢出,该服务是核心服务,分配了5G ...