spring boot 与缓存

  作者:记性不好的阁主

1、创建项目




Next





Next








Next



finish


spring boot 整合 mybatis省略


启动类上加上允许缓存注解


package com.laoxu.cache;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@MapperScan("com.laoxu.cache.mapper")
@SpringBootApplication
@EnableCaching
public class Springboot01CacheApplication {

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

}



在service层的方法上加上cacheable注解对这个方法进行缓存


package com.laoxu.cache.service.impl;

import com.laoxu.cache.bean.Employee;
import com.laoxu.cache.mapper.EmployeeMapper;
import com.laoxu.cache.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeMapper employeeMapper;

@Override
@Cacheable(cacheNames = "emp")
public Employee getEmployee(Integer id) {
System.out.println("查询" + id + "号员工");
return employeeMapper.getEmployee(id);
}
}



@Cacheable/@CachePut/@CacheEvict 主要的参数


cacheNames/value
指定缓存组件的名字,将方法的返回结果放在哪个缓存中
key
缓存数据使用的key,通过key获取缓存的数据,默认是方法参数的值作为key
keyGenerator
key的生成器,可以自定义生成的key
condition符合条件下才 缓存
unless符合条件下,不缓存
sync是否开启异步模式

SPEL元数据对照表





三个缓存操作注解默认执行时机



@Cacheable方法执行之前执行,查询缓存中是否包含缓存数据?取缓存 : 创缓存
@CachePut方法执行之后执行,更新缓存,缓存中有数据? 更新缓存 : 创建缓存
@CacheEvict方法执行之后执行,清除缓存



@Cacheable


案例一、


使用 方法名[参数值] 作为缓存的key


@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeMapper employeeMapper;

@Override
@Cacheable(cacheNames = "emp", key = "#root.methodName+'['+#id+']'")
public Employee getEmployee(Integer id) {
System.out.println("查询" + id + "号员工");
return employeeMapper.getEmployee(id);
}
}


案例二、


自定义key生成策略,使用 方法名[参数值] 作为缓存的key


创建自定义key生成配置类




package com.laoxu.cache.config;

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Method;
import java.util.Arrays;

@Configuration
public class MyCacheConfig {

@Bean("myKeyGenerator")
public KeyGenerator keyGenerator(){
return new KeyGenerator(){
@Override
public Object generate(Object o, Method method, Object... objects) {
return method.getName() + "[" + Arrays.asList(objects).toString() + "]";
}
};
}
}


在方法上使用自定义key


@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeMapper employeeMapper;

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


案例三、


只对id>1的数据做缓存


spel表达式:a0、p0、#root.args[0] 都表示方法的第一个参数


@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeMapper employeeMapper;

@Override
@Cacheable(cacheNames = "emp", keyGenerator = "myKeyGenerator", condition = "a0>1")
public Employee getEmployee(Integer id) {
System.out.println("查询" + id + "号员工");
return employeeMapper.getEmployee(id);
}
}



使用spel加上 方法名为aaa 限定条件


@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeMapper employeeMapper;

@Override
@Cacheable(cacheNames = "emp", keyGenerator = "myKeyGenerator", condition = "a0>1 and #root.methodName eq 'aaa'")
public Employee getEmployee(Integer id) {
System.out.println("查询" + id + "号员工");
return employeeMapper.getEmployee(id);
}
}


案例四、


只缓存 id>1 且 id!=2 的数据


@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeMapper employeeMapper;

@Override
@Cacheable(cacheNames = "emp", keyGenerator = "myKeyGenerator", condition = "a0>1 and #root.methodName eq 'aaa'")
public Employee getEmployee(Integer id) {
System.out.println("查询" + id + "号员工");
return employeeMapper.getEmployee(id);
}
}



@CachePut


案例、


在更新数据时 更新缓存,案例为 更新emp缓存中key为参数id值的缓存数据,须配合@Cacheable使用


@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeMapper employeeMapper;

@Override
@Cacheable(cacheNames = "emp")
public Employee getEmployee(Integer id) {
System.out.println("查询" + id + "号员工");
return employeeMapper.getEmployee(id);
}

@Override
@CachePut(cacheNames = "emp", key = "#result.id")
public Employee updateEmployee(Employee employee) {
System.out.println("更新" + employee);
employeeMapper.updateEmployee(employee);
return employee;
}
}



在有缓存的情况下,调用getEmployee()方法则会去缓存取出key为参数id值的方法返回结果,若此时调用updateEmployee()方法则会将key为id值的缓存数据更新为新的数据,此时若再次调用getEmployee()方法则得到的是更新后的结果。


@CacheEvict


案例一、


清除emp缓存中key为参数id值的缓存数据


@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeMapper employeeMapper;

@Override
@Cacheable(cacheNames = "emp")
public Employee getEmployee(Integer id) {
System.out.println("查询" + id + "号员工");
return employeeMapper.getEmployee(id);
}

@Override
@CachePut(cacheNames = "emp", key = "#result.id")
public Employee updateEmployee(Employee employee) {
System.out.println("更新" + employee);
employeeMapper.updateEmployee(employee);
return employee;
}

@Override
@CacheEvict(cacheNames = "emp", key = "#id")
public void deleteEmployee(Integer id) {
System.out.println("删除" + id);
}
}


在id为1有缓存的情况下,再次获取则不查询数据库,若调用deleteEmployee(1)方法,则清除 id=1的数据缓存,那么再次调用getEmployee(1)时,会再次重新查询数据库添加缓存,而调用getEmployee(2)或其他(除了1)则无需查询数据库。


案例二、


清除emp缓存中所有缓存数据


@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeMapper employeeMapper;

@Override
@Cacheable(cacheNames = "emp")
public Employee getEmployee(Integer id) {
System.out.println("查询" + id + "号员工");
return employeeMapper.getEmployee(id);
}

@Override
@CachePut(cacheNames = "emp", key = "#result.id")
public Employee updateEmployee(Employee employee) {
System.out.println("更新" + employee);
employeeMapper.updateEmployee(employee);
return employee;
}

@Override
@CacheEvict(cacheNames = "emp", key = "#id")
public void deleteEmployee(Integer id) {
System.out.println("删除" + id);
}

@Override
@CacheEvict(cacheNames = "emp", allEntries = true)
public void deleteAllEmployee() {
System.out.println("删除所有");
}
}



调用deleteAllEmployee()则清除emp缓存中的所有缓存数据,任何缓存都需要重新添加。


案例三、


方法调用前清除emp缓存中key为参数id值的缓存数据


@Override
@CacheEvict(cacheNames = "emp", beforeInvocation = true)
public void deleteEmployeeById(Integer id) {
System.out.println("删除" + id);
}


默认CacheEvict是方法调用你后执行,若方法执行过程中抛出异常中断了,那么久清除不了缓存了,beforeInvocation缺省为false,设置为true那么执行方法过程中无论抛出异常与否,都清除缓存。



相关推荐

评论 抢沙发

表情

分类选择