需要引入两组pom依赖,一组是开启springboot缓存支持,一组是ehcache依赖
<!-- Spring Boot 开启缓存支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 引入Ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
在resources目录下创建ehcache.xml文件,这里以查询电影为例(完整电影demo),新增一组自定义cache标签,name
设置为movie
,表示名称为movie的缓存对象。
说明
:我这里使用idea开发的,加载ehcache.xml时会报错,需要设置一下idea,操作路径 settings -> languages&frameworks -> schemas and dtds -> 添加地址 http://ehcache.org/ehcache.xsd
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<!--defaultCache:echcache 的默认缓存策略 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<!-- 自定义缓存策略 -->
<cache name="movie"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</cache>
</ehcache>
在application.properties中新增如下配置
spring.cache.ehcache.config=classpath:ehcache.xml
在App启动类中新增@EnableCaching
注解,开启缓存
@SpringBootApplication
@MapperScan("com.example.demo.mapper") //扫描mapper接口
@EnableCaching
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
在查询电影例子service实现方法中,添加@Cacheable
注解,并将缓存对象名称设置为movie
,与ehcache.xml中自定义的cache名称一一对应
@Override
@Cacheable(value = "movie")
public MovieInfo selectMovieInfoById(Long id) {
return this.movieInfoMapper.selectMovieInfoById(id);
}
在测试类中,查询两次电影信息,可以看到sql只打印了一次,说明第二次是从cache缓存中取的
package com.example.demo;
import com.example.demo.service.IMovieInfoService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
@Autowired
private IMovieInfoService movieInfoService;
@Test
public void selectMovieInfoById(){
//查询两次
System.out.println(this.movieInfoService.selectMovieInfoById(3L).toString());
System.out.println(this.movieInfoService.selectMovieInfoById(3L).toString());
}
}
在有些场景下,我们需要清除缓存重新加载,否则会影响数据正确性。
比如我们统计某张表数据条数,第一次查询10条(并缓存起来)。如果此时删除1条数据,再次查询会从缓存中获取,仍为10条,那这样就不正确了。所以,对于新增、删除类操作,我们要加上@CacheEvict
注解,清除缓存后重新加载。
@Override
@CacheEvict(value = "movie",allEntries = true)
public void addMovie(AddMovieReq req) {
MovieInfo info = new MovieInfo();
BeanUtils.copyProperties(req,info);
this.movieInfoMapper.insertMovieInfo(info);
}