SpringBoot缓存问题
缓存在实际开发中肯定会遇到的,为了减轻数据库的压力,很多的项目都使用了缓存来达到数据快速访问,可以给用户达到良好的体验。不然,客户一个请求响应半天,谁受得了。
但是,很多人在使用缓存中,会遇到缓存带来的麻烦。比如:数据库查询出来的数据和缓存数据不一致的问题。就是缓存滞后的问题导致的。
开启缓存
缓存的使用很简单,只需要在主类上加上@EnableCaching注解即可开启。
@SpringBootApplication
@EnableAutoConfiguration
@EnableCaching
public class SpringbootcacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootcacheApplication.class, args);
}
}
只有在这里开启注解,后面才可以使用缓存,否则无效的。
具体注解
@CacheConfig
@CacheConfig全局配置缓存,这个只需要配置到类上,就可以不需要二次配置,接收一个缓存的名字cacheNames。这里定义了缓存名字,其他地方就自动使用该缓存名字进行缓存。
@Cacheable
主要缓存注解。这个注解就是起到缓存查询不到,自动到数据库查询的功能效果。属性:cacheNames:缓存名字,condtion:缓存的条件,unless:不缓存的条件。缓存内部实现也是一个key value的形式。指定了key,就以key作为建进行缓存处理。
@CacheEvict
这个注解主要是清除缓存用的。我可以在更新,删除的时候,进行注解删除缓存。可以指定key和condition。这个key和@Cacheable里面的key保持一致 ,就可以删除对应的缓存。
实际使用缓存
@Service
@CacheConfig(cacheNames = “articleCache”)
public class ArticleService {
private AtomicInteger count =new AtomicInteger(0);
@Autowired
private ArticleMapper articleMapper;
/**
- 增加一篇文章 每次就进行缓存
- @return
*/
@CachePut
public Integer addArticle(Article article){
Integer result = articleMapper.addArticle(article.getTitle(), article.getAuthor(), article.getContent(), article.getFileName());
if (result>0) {
Integer lastInertId = articleMapper.getLastInertId();
System.out.println("–执行增加操作–id:" + lastInertId);
}
return result;
}
/**
- 获取文章 以传入的id为键,当state为0的时候不进行缓存
- @param id 文章id
- @return
*/
@Cacheable(key = “#id”,unless = “#result.state==0”)
public Article getArticle(Integer id) {
try {
//模拟耗时操作
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
final Article artcile = articleMapper.getArticleById(id);
System.out.println("–执行数据库查询操作"+count.incrementAndGet()+“次”+“id:”+id);
return artcile;
}
/**
- 通过id更新内容 清除以id作为键的缓存
- @param id
- @return
*/
@CacheEvict(key = “#id”)
public Integer updateContentById(String contetnt, Integer id) {
Integer result = articleMapper.updateContentById(contetnt, id);
System.out.println("–执行更新操作id:–"+id);
return result;
}
/**
- 通过id移除文章
- @param id 清除以id作为键的缓存
- @return
*/
@CacheEvict(key = “#id”)
public Integer removeArticleById(Integer id){
final Integer result = articleMapper.removeArticleById(id);
System.out.println(“执行删除操作,id:”+id);
return result;
}
}
这里缓存加在service层来实现,具体的实现都是key为id作为建来保存,然后根据key来更新删除缓存。