SpringBoot2--缓存

本文详细介绍了SpringBoot2中缓存的使用,包括JCache(JSR-107)规范的解析,Spring缓存抽象的实现,如@Cacheable、@CachePut和@CacheEvict等注解的使用,以及SpringBoot如何配置和利用Redis进行缓存操作,还讲解了如何自定义RedisTemplate以实现JSON序列化。
摘要由CSDN通过智能技术生成

前言

缓存在数据访问过程中具有重要作用,它能够提高访问效率,还能存储临时数据

一、JCache(JSR-107)规范

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设置。
在这里插入图片描述
但是JSR-107规范比较麻烦,一般不用

二、Spring缓存抽象

Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术; 并支持使用JCache(JSR-107)注解简化我们开发;
• Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;
• Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache , ConcurrentMapCache等;
• 每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。
• 使用Spring缓存抽象时我们需要关注以下两点;
1、确定方法需要被缓存以及他们的缓存策略
2、从缓存中读取之前缓存存储的数据

1、准备

1)导入依赖

  <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-cache</artifactId>
  </dependency>

2)全局配置文件

spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring_cache?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=chen
        
#开启驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true

#开启日志打印
loggi

3)新建Bean

package com.sxt.springboot.bean;

public class Employee {
   
	
	private Integer id;
	private String lastName;
	private String email;
	private Integer gender; //性别 1男  0女
	private Integer dId;
	
	
	public Employee() {
   
		super();
	}

	
	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;
	}
	@Override
	public String toString() {
   
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId="
				+ dId + "]";
	}
}

4)新建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} where id=#{id}")
	public void updateEmp(Employee emp);

	@Delete("delete from employee where id={id}")
	public void deleteEmpById(Integer id);

	@Delete("insert into employee(lastName,email,gender,d_id) values(#{lastName},#{email},#{gender},#{dId})")
	public void insertEmp(Employee emp);
	
	@Select("select * from employee where lastName=#{lastName}")
	public Employee getEmployeeByLastName(String lastName);
}
@MapperScan("com.sxt.springboot.mapper")
@SpringBootApplication
public class Application {
   

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

}

5)新建Controller和Service

@RestController
public class EmployeeController {
   

	@Autowired
	EmployeeService  employeeService;

	@GetMapping("/emp/{id}")
	public Employee getEmp(@PathVariable("id")Integer id){
   
		Employee emp = employeeService.getEmp(id);
		return emp;
	}
}
@Service
public class EmployeeService {
   

	@Autowired
	EmployeeMapper employeeMapper;

	public Employee getEmp(Integer id){
   
		return employeeMapper.getEmpById(id);
	}
	
}
2、使用
几个重要概念&缓存注解
Cache 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等
CacheManager 缓存管理器,管理各种缓存(Cache)组件
@Cacheable 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,以后需要相同数据直接从缓存取出
@CacheEvict 清空缓存
@CachePut 保证方法被调用,又希望结果被缓存。
@EnableCaching 开启基于注解的缓存
keyGenerator 缓存数据时key生成策略
serialize 缓存数据时value序列化策略
1 @Cacheable/@CachePut/@CacheEvict 主要的参数 1
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:@Cacheable(value=”mycache”) 或者@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存/清除缓存 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
allEntries (@CacheEvict ) 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 例如:@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation (@CacheEvict) 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 例如:@CachEvict(value=”testcache”,beforeInvocation=true)

在这里插入图片描述
首先要开启基于注解的缓存@EnableCaching

@MapperScan("com.sxt.springboot.mapper")
@EnableCaching
@SpringBootApplication
public class Application {
   

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

}
1)@Cacheable

新建Service


@Service
public class EmployeeService {
   

	@Autowired
	EmployeeMapper employeeMapper;

	/*
	* 能够根据方法的请求参数对其结果进行缓存,以后需要相同数据直接从缓存取出
	*几个属性:
	*     1.cacheNames/value:指定缓存的名字,可以指定多个
	*     2.key:默认按照方法的所有参数进行组合,可以使用spel
	*     3.keyGenerator:可以自己指定,和key只能选一个
	*     4.cacheManager
	*     5.condition:"#a0>0" 第一个参数的值大于1
	*     6.unless:除了
	*     7.sync:是否使用异步模式
	* 执行之前检查缓存有没有这个数据,默认按照参数作为key来查询,如果没有就
	* 执行方法且将结果放入缓存
	* */
	@Cacheable(cacheNames={
   "emp"},key = "#root.methodName",condition = "#a0>0",unless = "#a0==2")
	public Employee getEmp(Integer id){
   
		return employeeMapper.getEmpById(id);
	}
}

Controller测试

@RestController
public class EmployeeController {
   

	@Autowired
	EmployeeService  employeeService;

	@GetMapping("/emp/{id}")
	public Employee getEmp(@PathVariable("id")Integer id){
   
		Employee emp = employeeService.getEmp(id);
		return emp;
	}
}

也可以自定义keyGenerator

@Configuration
public class MyCacheConfig {
   

	@Bean("myKeyGennerator")
	public KeyGenerator keyGenerator(){
   
		 return new KeyGenerator(){
   

			 @Override
			 public Object generate(Object o, Method method, Object... objects) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值