spring中基于注解使用ehcache
继续上篇,这篇介绍服务层缓存,基于注解的方式使用ehcache
注解的标签主要有4个:@Cacheable、@CacheEvict、@CachePut、@Caching,他们的用法是:
@Cacheable:调用方法时会先从缓存中取,如果没有就执行方法,然后将结果存入缓存 @CacheEvict:方法执行后会清空缓存 @CachePut:无论有没有缓存都会执行方法,然后将结果存入缓存 @Caching:组合多个cache注解使用
一、修改配置文件
1、修改spring-context-ehcache.xml文件,加入:
<!-- 开启缓存注解 --> <cache:annotation-driven cache-manager="cacheManager" /> <!-- spring的ehcache缓存配置 --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="ehcacheManager"></property> </bean>
如果ehcache的bean的id就叫"cacheManager",cache-manager可以不加,因为默认值就是这个
2、修改ehcache-context.xml文件,加入:
<cache name="testDao" maxEntriesLocalHeap="10000" maxEntriesLocalDisk="100000" overflowToDisk="true" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" />
"testDao"是接下来要用到的缓存名称,一定要加好,不然注解使用缓存时会提示找不到
二、在方法中加入cache注解
修改testDao.java类:
@SuppressWarnings("unchecked") @Cacheable(value="testDao", key="'list'") public List<testInfo> getList() { String hql = "from testInfo"; Query query = sessionFactory.getCurrentSession().createQuery(hql); query.setCacheable(true); return query.list(); } @Cacheable(value="testDao", key="'view' + #id") public testInfo getInfo(String id) { return (testInfo) sessionFactory.getCurrentSession().get(testInfo.class, id); } @Caching( put={@CachePut(value="testDao", key="'view' + #testInfo.id")}, evict={@CacheEvict(value="testDao", key="'list'")} ) public testInfo update(testInfo testInfo) { testInfo.setName("789"); //update return testInfo; } @Caching( evict={ @CacheEvict(value="testDao", key="'view' + #id"), @CacheEvict(value="testDao", key="'list'")} ) public void delete(String id) { //delete } @CacheEvict(value="testDao", allEntries=true) public void deleteAll() { //deleteAll }
查询方法使用@Cacheable注解,value属性一定要加,更新方法使用@CachePut注解,还需要清除相关的list缓存,删除方法使用@CacheEvict注解,"allEntries=true"表示清空所有缓存。
Controller的方法也可以使用缓存注解。
三、运行测试
1、修改HelloController.java类,添加更新和删除的方法:
@RequestMapping("update/{id}") public String update(@PathVariable("id") String id, HttpServletRequest request) { testInfo testInfo = new testInfo(); testInfo.setId(id); testDao.update(testInfo); return "redirect:/hello/list2"; } @RequestMapping("delete/{id}") public String delete(@PathVariable("id") String id, HttpServletRequest request) { testDao.delete(id); return "redirect:/hello/list2"; }
2、修改list.jsp页面,修改table的内容为:
<table border="1" width="150px"> <tr> <th>列1</th> <th>列2</th> </tr> <c:forEach items="${testList}" var="item"> <tr> <td>${item.id}</td> <td> <a href="${path}/hello/view/${item.id}" target="_blank">${item.name}</a> <a href="${path}/hello/update/${item.id}">更新</a> <a href="${path}/hello/delete/${item.id}">删除</a> </td> </tr> </c:forEach> </table>
3、测试
在这两个地方设置断点
第一次访问list和view的时候会命中断点,第二次就不会了
点击更新后,list的断点重新命中,再点击"233",没有命中断点,内容变成了"789",因为更新操作结束后更新了缓存
点击删除后,list和view的断点都会重新命中,因为删除操作后清空了缓存
实例代码地址:https://github.com/ctxsdhy/cnblogs-example