Spring Boot缓存技术
Spring Boot支持的缓存种类较多,例如EhCache、Redis、JCache 等,其中我们使用较多的是EhCache。
Spring Boot使用Cache之EhCache
首先我们可以在pom中添加依赖
<!-- caching --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency> </dependencies>
在Spring Boot配置文件中写入配置
spring.cache.type=ehcache spring.cache.ehcache.config=classpath:config/ehcache.xml
此处classpath为我们定义的缓存配置xml文件路径
创建encache.xml文件,路径和内容如下
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"> <cache name="mxCache" eternal="false" maxEntriesLocalHeap="0" timeToIdleSeconds="50"> </cache> </ehcache>
eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false
maxEntriesLocalHeap:堆内存中最大缓存对象数,0没有限制
timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可无限期地处于空闲状态.写一个EhCacheService接口
public interface EhCacheService { User selectById(Integer id); User updateById(User user); String deleteById(Integer id); }
写接口的实现类EhCacheServiceImpl,代码如下
@CacheConfig(cacheNames = "mxCache") @Repository public class EhCacheServiceImpl implements EhCacheService { @Autowired private TestUserDao testUserDao; @Cacheable(key = "#p0") @Override public User selectById(Integer id) { System.out.println("查询功能,缓存找不到,直接读库, id=" + id); User user = testUserDao.getOne(1); return user; } @CachePut(key = "#p0") @Override public User updateById(User user) { System.out.println("更新功能,更新缓存,直接写库, id=" + user); return testUserDao.save(user); } @CacheEvict(key = "#p0") @Override public String deleteById(Integer id) { System.out.println("删除功能,删除缓存,直接写库, id=" + id); return "清空缓存成功"; } }
此处@CacheConfig(cacheNames = “mxCache”)注解的cacheNames为我们在配置文件encache.xml中配置的name
创建测试的CacheController,
@RestController @RequestMapping("/cache") public class CacheController { @Autowired private EhCacheService ehCacheService; @RequestMapping(value = "/select", method = RequestMethod.GET) public String get(@RequestParam(defaultValue = "1") Integer id) { User user = ehCacheService.selectById(id); return user.toString(); } @RequestMapping(value = "/update", method = RequestMethod.GET) public String update(@RequestParam(defaultValue = "1") Integer id) { User user = ehCacheService.selectById(id); user.setUsername("测试cache"); ehCacheService.updateById(user); return user.toString(); } @RequestMapping(value = "/del", method = RequestMethod.GET) public String del(@RequestParam(defaultValue = "1") Integer id) { return ehCacheService.deleteById(id); } }
启动项目之前,在Spring Boot启动类加@EnableCaching注解
@EnableCaching @SpringBootApplication public class SpringBootDemo9Application { public static void main(String[] args) { SpringApplication.run(SpringBootDemo9Application.class, args); } }
- 由于我们在数据库已经有一条数据,
访问测试地址http://127.0.0.1:8080/cache/select,返回页面
控制台显示,再次刷新页面,则会发现控制台不显示该语句,说明现在已经是在缓存取得数据
访问测试地址http://127.0.0.1:8080/cache/del,返回页面
控制台显示,由于我们在代码写的删除并没有真的删除,因此这里不会真的删除数据库数据,但是已经清掉了id为1的缓存数据
再次访问测试地址http://127.0.0.1:8080/cache/select,会发现又在数据库中取值并存于缓存中了
访问测试地址http://127.0.0.1:8080/cache/update,返回页面
控制台显示
此时数据库里的数据已经被更改,且缓存也同时被修改.
缓存注解解释
1、@Cacheable:主要用来配置方法,能够根据方法的请求参数对其结果进行缓存。即当重复使用相同参数调用方法的时候,方法本身不会被调用执行,即方法本身被略过了,取而代之的是方法的结果直接从缓存中找到并返回了。
参数介绍:
value:缓存的名字,必须指定至少一个。
key:缓存的key,可以为空,如果指定要按照SpEL表达式编写;如果不指定,则缺省按照方法的所有参数进行组合。
condition:缓存的条件,可以为空,使用SpEL编写,返回true或者false,只有为true才能缓存。
例子:
@Cacheable(value="shops:detail",key="'id:'+#p0")
public Shop getById(String id);
- 这两行代码的意思是指,缓存的名字为:shops:detail,其中缓存的key值为id:id的值。其中#p0的意思是指加有@Cacheable注解的方法中的第一个参数
2、@CacheEvict:主要对方法配置,用来标记要清空缓存的方法,当这个方法被调用并满足一定条件后,即会清空缓存。
参数解析:
- value:缓存的位置,不能为空。
- key:缓存的key,默认为空。
- condition:触发的条件,只有满足条件的情况才会清楚缓存,默认为空,支持SpEL。
- allEntries:true表示清除value中的全部缓存,默认为false。
例子:
@CacheEvict(value="shops:detail",key="'id:'+#p0['id']",condition="#p0['id']>0")
public Shop getById(Map<String, Object> param);
- 上面两行代码表示,只要param中key为id的值大于0,将进行缓存操作,否则直接调用调用getById方法返回结果。
@Caching(evict={@CacheEvict(value=”shops:brief”,allEntries=true)})
public void delete(String id);
上面两行代码表示,只要执行了delete方法,就刷新缓存名为”shops:brief”下面的所有缓存。
3、@CachePut:主要针对方法的配置,能够根据方法的请求参数对其结果进行缓存,和@Cacheable不同的是,它每次都会触发真实方法的调用。
@CachePut(value="shops:detail",key="'id:'+#p0['id']")
public Shop update(Map<String, Object> param);
- 上面两行代码表示,当调用update方法时,该方法体会被执行,并且执行的结果会返回写入到缓存中。