缓存注解Cache

SpringBoot缓存注解 @CacheConfig、@Cacheable、@CachePut、@CacheEvict、@Caching

将方法的运行结果进行缓存;以后再要有相同的数据,直接从缓存中获取,不用调用方法;
CacheManager管理多个Cache组件,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字;
在这里插入图片描述

@Cacheable

@Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。Spring在缓存方法的返回值时是以键值对进行缓存的,值就是方法的返回结果,至于键的话,Spring又支持两种策略,默认策略和自定义策略,这个稍后会进行说明。需要注意的是当一个支持缓存的方法在对象内部被调用时是不会触发缓存功能的。
Cache中value属性是必须指定的,其表示当前方法的返回值是回被缓存在哪个Cache上的。cacheNames/value;指定缓存的名字
将方法的返回值放到哪个缓存中 其盛放的只一个数组的方式存放的
@Cacheable注解在调用方法之前 查看是否有缓存

cacheable上的value注解
   @Cacheable("emp")
   public Employee get(Integer id) {
   	  System.out.println("查询"+id+"号员工");
      return null;
   }
   @Cacheable({"emp1", "emp2"})
   public Employee  find(Integer id) {
      return null;
   }
	@Cacheable(cacheNames = {"emp"})
	public Employee getEmp(Integer id){
		System.out.println("查询"+id+"号员工");
		Employee emp=employeeMapper.getEmpById(id);
		return emp;
	}
key属性的应用

key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。
key:缓存数据使用的key;可以用他来指定。默认是使用方法参数的值 1-方法的返回值
编写SpEl表达式:#root.methodName当前被调用的方法名
#root.method.name当前被调用的方法
#root.target当前被调用的目标对象
#root.args[0]当前被调用的方法的参数列表
#root.targetClass当前被调用的目标对象类

//这里的#id表示入参时的id   
@Cacheable(cacheNames = {"emp"},key="#id")
    public Employee getEmp(Integer id){
        System.out.println("查询"+id+"号员工");
        Employee emp=employeeMapper.getEmpById(id);
        return emp;
    }
//key中的#id和#root.args[0]一样都是将id作为key
	@Cacheable(cacheNames = "emp",key="#root.args[0]")
		public Employee getEmp(Integer id){
		System.out.println("查询"+id+"号员工");
		Employee emp=employeeMapper.getEmpById(id);
		return emp;
	}
@Cacheable(value="users", key="#p0")
   public User find(Integer id) {
      return null;
   }
//如果是对象入参时可以"."出来
@Cacheable(value="users", key="#user.id")
   public User find(User user) {
      return null;
   }
@Cacheable(value="users", key="#p0.id")
   public User find(User user) {
      return null;
   }
//可以自己指定key与不指定是一样的效果默认使用入参的id  如果入参是一个对象或map可以.出来
@Cacheable(cacheNames = {"emp"},key = "#root.methodName+'['+#id+']'")
public Employee getEmp(Integer id){
	System.out.println("查询"+id+"号员工");
	Employee emp=employeeMapper.getEmpById(id);
	return emp;
}

当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。

@Cacheable(value={"users", "xxx"}, key="caches[1].name")
   public User find(User user) {
      return null;
   }

在这里插入图片描述

condition:指定合适条件的情况下才缓存;当参数的id大于0时才将方法的运行结果进行缓存
//condition="#id>0"  id大于0时才将方法运行的结果进行缓存
@Cacheable(cacheNames = "emp",condition="#id>0")
public Employee getEmp(Integer id){
System.out.println("查询"+id+"号员工");
Employee emp=employeeMapper.getEmpById(id);
return emp;
}
//condition满足条件时开启缓存  不满足条件不进行缓存
@Cacheable(cacheNames = "emp",condition="#id>0")
	public Employee getEmp(Integer id){
	System.out.println("查询"+id+"号员工");
	Employee emp=employeeMapper.getEmpById(id);
	return emp;
}

//可以写很多
如:condition="#id>0 and #root.methodName eq 'aa'"
unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到的结果进行判断
//unless指定的条件为true时不会进行缓存
@Cacheable(cacheNames = "emp",condition="#id>0",unless="#result == null")
public Employee getEmp(Integer id){
	System.out.println("查询"+id+"号员工");
	Employee emp=employeeMapper.getEmpById(id);
	return emp;
}

@CachePut

@CachePut即调用方法,又跟新缓存数据
修改了数据库的某个数据,同时更新缓存
cacheput是方法运行完后才在缓存中放东西

在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
@CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。

//key = "#employee.id"(使用传入的参数的id) 与key = "#result.id"相同(使用返回后的id)
@CachePut(value = "emp",key = "#result.id")
public Employee updateEmp(Employee employee){
   System.out.println("updateEmp"+employee);
   employeeMapper.updateEmp(employee);
   return employee;
}

cacheable与cacheput注解的不同是:cacheable注解是在调用之前查看缓存中是否有key缓存的数据
cacheput先调用目标方法,将目标方法的结果缓存起来 指定id后才能跟新缓存中的东西,没指定只是会修改数据库中的值而不是修改缓存中的
cacheable中的key定义不能使用#result. 因为是方法之前进行的缓存检查操作

@CacheEvict

@CacheEvict;缓存清除
删除某个数据后将其从缓存中清除出去
key:指定要清除的数据
@CacheEvict(value = “emp”,key = “#id”,allEntries = true)
allEntries = true 是否删除缓存中的所有数据
beforeInvocation=false:缓存的清除是否在方法之前执行
默认代表是在方法执行之后执行;如果出现异常缓存就不会清除
@CacheEvict(value = “emp”,beforeInvocation = true,key = “#id”)
代表清除缓存的操作是在方法运行之前执行无论方法是否出现异常缓存都清除

@CacheEvict(value = "emp",beforeInvocation = true,key = "#id")
public void deleteEmp(Integer id){
   employeeMapper.deleteEmpById(id);
}

@Caching

@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。
@Caching 可以进行多缓存 定义复杂的缓存结果
如果标注CachePut则cacheable相当于失效,有cacheable方法一定执行

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

也可以自定义缓存可以的配置类
方法一

@Configuration
public class MyCacheConfig {

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

            @Override
            public Object generate(Object target, Method method,Object... params){
                return method.getName()+"["+ Arrays.asList(params).toString()+"]";
            }
        };
    }
}

使用自定义的配置类进行缓存key

@Cacheable(cacheNames = {"emp"},keyGenerator = "myKeyGenerator")
public Employee getEmp(Integer id){
	System.out.println("查询"+id+"号员工");
	Employee emp=employeeMapper.getEmpById(id);
	return emp;
}

方法二

//自定义缓存注解类
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Cacheable(value="users")
public @interface MyCacheable {
 
}

那么在我们需要缓存的方法上使用@MyCacheable进行标注也可以达到同样的效果。

   @MyCacheable
   public User findById(Integer id) {
      System.out.println("find user by id: " + id);
      User user = new User();
      user.setId(id);
      user.setName("Name" + id);
      return user;
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值