package com.jaeson.springstudy.cache;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.jaeson.hibernatestudy.bean.Student;
@RunWith(SpringJUnit4ClassRunner.class)
//配置@ContextConfiguration注解并使用该注解的locations属性指明spring和配置文件
@ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:spring-hibernate.xml", "classpath:spring-mybatis.xml", "classpath:spring-ehcache.xml" })
public class TestCache {
@Autowired
private StudentManager manager;
public void setStudentManager(StudentManager manager) {
this.manager = manager;
}
@Test
public void testEhcache() {
Student stu = manager.findById("025b49ab208a4a358dfb4b1b53acd9d6");
System.out.println("====================" + stu.getName());
stu = manager.findById("025b49ab208a4a358dfb4b1b53acd9d6");
System.out.println("====================" + stu.getName());
manager.removeAll();
stu = manager.findById("025b49ab208a4a358dfb4b1b53acd9d6");
System.out.println("====================" + stu.getName());
stu = new Student();
stu.setName("testEhcache");
stu.setSex(1);
stu = manager.save(stu);
System.out.println("after save====================" + stu.getId());
stu = manager.findById(stu.getId());
System.out.println("====================" + stu.getName());
manager.delete(stu);
stu = manager.findById(stu.getId());
System.out.println("after delete====================" + (stu == null ? null : stu.getName()));
}
}
package com.jaeson.springstudy.cache;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
//import org.springframework.cache.annotation.CacheConfig;
import com.jaeson.hibernatestudy.bean.Student;
import com.jaeson.hibernatestudy.bean.Clazz;
import com.jaeson.springstudy.dao.StudentDao;
@Service
@Transactional
//@CacheConfig(cacheNames="studentCache", key="#p0")
public class StudentManager {
@Autowired
@Qualifier("jdbcTemplateStudentDao")
private StudentDao studentDao;
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}
//对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,
//如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。
//不指定key时,使用默认的key生成策略KeyGenerator。
//方法没有参数时,使用SimpleKey.EMPTY
//只有一个参数时,使用该参数作为key
//多于一个参数时,使用包含所有参数的SimpleKey(所有参数的hashCode)
@Cacheable("studentCache")
public Student findById(String id) {
return this.studentDao.findById(id);
}
//将返回结果放入cache中,并使用EL指定的key生成策略
@Cacheable(cacheNames="studentCache", key="#id")
public List<Student> findByClassid(String id) {
return this.studentDao.findByClassid(id);
}
//key="#p0.id" 表示第一个参数的id属性
@Cacheable(cacheNames="studentCache", key="#p0.id")
public List<Student> findByClass(Clazz clazz) {
return this.studentDao.findByClassid(clazz.getId());
}
//与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,
//而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
@CachePut(cacheNames="studentCache", key="#entity.id")
public Student save(Student entity) {
entity.setId(this.studentDao.save(entity));
return entity;
}
//每次都直接执行update方法,并将结果放入cache
@CachePut(cacheNames="studentCache", key="#entity.id")
public Student update(Student entity) {
this.studentDao.update(entity);
return entity;
}
//@CacheEvict移除cache中相应的缓存项,evict操作默认在方法返回时进行,如果方法执行中抛出异常,则evict操作不会发生。
//beforeInvocation=true表示在方法调用之前先进行cache的evict操作,allEntries=true表示清除所有的缓存项。
@CacheEvict(cacheNames="studentCache", key="#entity.id", beforeInvocation=true)
public void delete(Student entity) {
this.studentDao.delete(entity);
}
//移除cache中相应的缓存项
@CacheEvict("studentCache")
public void deleteById(String id) {
this.studentDao.deleteById(id);
}
//移除指定cache中的所有缓存项
@CacheEvict(cacheNames="studentCache", allEntries=true)
public void removeAll() {
System.out.println("removeAll is called, evict all cache entry");
}
}
ehcache.xml
<?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"/> <!-- name:缓存名称。 maxElementsInMemory:缓存最大个数。 eternal:对象是否永久有效,一但设置了,timeout将不起作用。 timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。 仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。 仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。 diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 maxElementsOnDisk:硬盘最大缓存个数。 diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。 默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 clearOnFlush:内存数量最大时是否清除。 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="1000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <persistence strategy="localTempSwap"/> </defaultCache> <cache name="studentCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" memoryStoreEvictionPolicy="LRU"/> </ehcache>
spring-ehcache.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd" > <!-- 启用cache注解扫描,@CacheConfig/@Cacheable/@CachePut/@CacheEvict/@Caching --> <cache:annotation-driven /> <!-- ehcache配置 --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcacheManager"/> <!-- EhCache library setup --> <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="ehcache.xml"/> </beans>
pom.xml
<!-- ehcache --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.1</version> </dependency>
Running com.jaeson.springstudy.cache.TestCache
[INFO][2016-04-28 18:23:38] com.jaeson.springstudy.dao.impl.JdbcTemplateStudentDaoImpl.findById(JdbcTemplateStudentDaoImpl.java:89) select s.id as id, s.name as name, s.sex as sex, s.clazz_id as student_clazz_id, c.id as clazz_id, c.name as clazz_name from student s left outer join clazz c on s.clazz_id = c.id where s.id = ?
====================jaesonchen
====================jaesonchen
removeAll is called, evict all cache entry
[INFO][2016-04-28 18:23:39] com.jaeson.springstudy.dao.impl.JdbcTemplateStudentDaoImpl.findById(JdbcTemplateStudentDaoImpl.java:89) select s.id as id, s.name as name, s.sex as sex, s.clazz_id as student_clazz_id, c.id as clazz_id, c.name as clazz_name from student s left outer join clazz c on s.clazz_id = c.id where s.id = ?
====================jaesonchen
[INFO][2016-04-28 18:23:39] com.jaeson.springstudy.dao.impl.JdbcTemplateStudentDaoImpl.save(JdbcTemplateStudentDaoImpl.java:160) insert into student (id, name, sex) values(?, ?, ?)
after save====================9ac4fb417acc4b06ad3a78a339d4f6d4
====================testEhcache
[INFO][2016-04-28 18:23:39] com.jaeson.springstudy.dao.impl.JdbcTemplateStudentDaoImpl.deleteById(JdbcTemplateStudentDaoImpl.java:187) delete from student where id = ?
[INFO][2016-04-28 18:23:39] com.jaeson.springstudy.dao.impl.JdbcTemplateStudentDaoImpl.findById(JdbcTemplateStudentDaoImpl.java:89) select s.id as id, s.name as name, s.sex as sex, s.clazz_id as student_clazz_id, c.id as clazz_id, c.name as clazz_name from student s left outer join clazz c on s.clazz_id = c.id where s.id = ?
after delete====================null