Spring boot (三) —— spring 缓存
关于spring缓存如何操作
- 添加cache依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
- 在启动类配置:@EnableCaching
- 然后在接口方法实现处添加缓存注解
- 缓存之后,程序调用该类实例的任何方法,只要传入的参数相同,Spring将不会真正执行该方法,而是直接根据传入的参数去查找缓存中的数据
关于缓存注解
@Cacheable | 主要针对方法配置,能够根据方法的请求参数对其进行缓存 |
@CacheEvict | 清空缓存 |
@CachePut | 保证方法被调用,又希望结果被缓存。 |
@CacheConfig | 这个注解的的主要作用就是全局配置缓存,比如配置缓存的名字(cacheNames),只需要在类上配置一次,下面的方法就默认以全局配置为主,不需要二次配置,节省了部分代码。 |
这是会用到的四种注解,其中前三种注解的主要参数解释如下:
value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个,其实就是缓存空间名,假如你在CacheConfig上填了,就可以不填 |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写, |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false, |
unless | 否定缓存。当条件结果为TRUE时,就不会缓存。 |
allEntries | 是否清空所有缓存内容,缺省为 false,如果指定为 true, |
beforeInvocation | 是否在方法执行前就清空,缺省为 false,如果指定为 true, |
这个缓存注解是通过识别key来确定是否要调用缓存的,而这个key一般由我们动态设置,多数是通过传进来的某个参数(如id)。
举个例子:
实体层:
@Entity
@Table(name = "Tester")
public class Tester {
@Id
@SequenceGenerator(name = "generator_Tester", sequenceName = "s_Tester", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "generator_Tester")
@Column(name = "id")
private Long id;
private String name;
private String value1;
private String value2;
private Integer age;
}
Service层:
@Service
@CacheConfig(cacheNames = {"myCache"})
//将本类的所有缓存注解的value命名为myCache
public class TestService {
@Autowired
private TesterRepository testerRepository;
@Cacheable(key = "#age")
public List<Tester> GetAll(Integer age){
try {
//模拟耗时操作
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return testerRepository.findAllByAge(age);
}
@CacheEvict(key = "#tester.age")
public List<Tester> Create(Tester tester){
Tester tester1 = new Tester(tester.getName(),tester.getValue1(),tester.getValue2(),tester.getAge());
testerRepository.save(tester1);
List<Tester> testerList = testerRepository.findAll();
return testerList;
}
@CacheEvict(allEntries = true)
public List<Tester> Delete(Tester tester){
testerRepository.delete(tester.getId());
List<Tester> testerList = testerRepository.findAll();
return testerList;
}
}
Controller层:
@RestController
@RequestMapping("/test")
public class TesterController {
@Autowired TestService testService;
@GetMapping("/getall")
public List<Tester> getAll(@RequestParam("age") Integer age){
if (age == null)
return null;
Long start = System.currentTimeMillis();
List<Tester> testerList = testService.GetAll(age);
Long end = System.currentTimeMillis();
System.out.println("--执行数据库查询操作"+(end - start));
return testerList;
}
@PostMapping("/create")
public List<Tester> createOne(@RequestBody Tester tester){
if (tester == null){
return null;
}
return testService.Create(tester);
}
@PostMapping("/delete")
public List<Tester> deleOne(@RequestBody Tester tester){
if (tester == null){
return null;
}
return testService.Delete(tester);
}
}
在这个例子中,我们就实现了对按照age查询的结果进行缓存,并在对应age的数据发生更新或删除后清除缓存的操作,要点是在service层进行方法的缓存注解。
缓存是优化项目的一个重要手段,所以今天介绍一种简单的缓存手段,局限性也很明显,就是不够灵活,但对于一些小项目而言是足够了。