一,ehcache缓存
在这里,我们首先讨论一个问题,什么是缓存,我们为什么要使用缓存?缓存实际上是为了减轻数据库服务器的负载,使用缓存,我们可以将一些常用的数据放入缓存,因为这些数据经常性的使用,大大增加了服务器的负载,但是当放入缓存后,在使用这些数据的时候,首先会从缓存中查找,如果缓存中有就读取,不会再到数据库中查找,如果缓存中没有,才会到数据库中查询,在这里,需要注意的是,ehcache的是将数据放入jvm内存中,也就是说当次缓存在本次服务器启动期间有效,下次服务器启动将会失效。
二,如何使用ehcache技术进行缓存?
使用ehcache进行缓存其实非常简单,在这里简要介绍一下,然后我们通过一个实例来介绍具体怎么使用。
Ehcache的类层次模型主要为三层,最上层的是CacheManager,他是操作Ehcache的入口。我们可以通过CacheManager.getInstance()获得一个单个的CacheManager,或者通过CacheManager的构造函数创建一个新的CacheManager。每个CacheManager都管理着多个Cache。而每个Cache都以一种类Hash的方式,关联着多个Elemenat。而Element则是我们用于存放要缓存内容的地方。
ehcache的刷新策略
ehcache的刷新策略是当缓存在放入的时候记录一个放入时间,它是用Lazy Evict的方式,在取的时候同设置的TTL比较
ehcache缓存的3种清空策略:
1 FIFO,先进先出
2 LFU,最少被使用,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
3 LRU,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
事件处理
可以为CacheManager添加事件监听,当对CacheManager增删Cache时,事件处理器将会得到通知。要配置事件处理,需要通过ehcache的配置文件来完成。
可以为Cache添加事件监听,当对Cache增删Element时,事件处理器将会得到通知。要配置事件处理,需要通过ehcache的配置文件来完成。
ehcache参数配置:
maxInMemory - 设定内存中创建对象的最大值。
eternal - 设置元素(译注:内存中对象)是否永久驻留。如果是,将忽略超时限制且元素永不消亡。
timeToIdleSeconds - 设置某个元素消亡前的停顿时间。也就是在一个元素消亡之前,两次访问时间的最大时间间隔值。这只能在元素不是永久驻留时有效(译注:如果对象永恒不灭,则设置该属性也无用)。
如果该值是 0 就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds - 为元素设置消亡前的生存时间。也就是一个元素从构建到消亡的最大时间间隔值。这只能在元素不是永久驻留时有效。
overflowToDisk - 设置当内存中缓存达到maxInMemory 限制时元素是否可写到磁盘上。
好了,经过上面的介绍,下面我们来看一个简单的实例。我们将会查询一条数据后然后删除这条数据再次查询任然能查询到该结果,因为它已经存入到缓存中了,即使数据库中不存在该数据。
首先,要引入pom。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
ehcache.xml文件
<ehcache>
<!-- 磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存 path:指定在硬盘上存储对象的路径 -->
<diskStore path="java.io.tmpdir" />
<!-- defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理 maxElementsInMemory:设置了缓存的上限,最多存储多少个记录对象
eternal:代表对象是否永不过期 timeToIdleSeconds:最大的发呆时间 timeToLiveSeconds:最大的存活时间 overflowToDisk:是否允许对象被写入到磁盘 -->
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" />
<!-- cache:为指定名称的对象进行缓存的特殊配置 name:指定对象的完整名 -->
<cache name="ehcache" maxElementsInMemory="10000"
eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"
overflowToDisk="true" />
</ehcache>
上面是配置文件,然后我们将会在DAO层进行缓存处理。代码如下。
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import cn.shinelon.entity.User;
@CacheConfig(cacheNames="ehcache")
public interface User1Dao {
//使用ehcache缓存技术
@Select("select * from user where id=#{id}")
@Cacheable
public User select(@Param("id")int id);
}
注意,上面的注释@CacheConfig(cacheNames=”ehcache”)的属性cacheNames的值与配置文件中cache中name的属性一致,@Cacheable注解表示我们这里将使用缓存。最后,我们来看一下controller层的代码。
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import cn.shinelon.config.DBConfig1;
import cn.shinelon.config.DBConfig2;
import cn.shinelon.entity.User;
import cn.shinelon.test1.dao.User1Dao;
import cn.shinelon.test1.services.User1Service;
import cn.shinelon.test2.services.User2Service;
@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan(basePackages={"cn.shinelon.aop","cn.shinelon.config","cn.shinelon.datasource",
"cn.shinelon.test1","cn.shinelon.test2"})
@RestController
@EnableConfigurationProperties(value= {DBConfig1.class,DBConfig2.class})
@EnableCaching //支持缓存
public class UserController {
//测试缓存
@Autowired
private User1Dao user1Dao;
@ResponseBody
@RequestMapping("/cache")
public String cache(int id) {
return user1Dao.select(id).toString();
}
然后,我们访问使用localost:8080/cache?id=4来访问服务器,可以访问到数据,然后删除数据库中的这条数据,继续访问,还是可以查询到数据,因为这条数据已经存入到缓存中了,这时,有一个问题,有时我们不需要缓存,这时该怎么清除缓存呢?这很简单,我们只需要在controller层通过cacheManager来管理清除缓存即可,需要插入的代码是:
//清除缓存
@Autowired
private CacheManager cacheManager;
@ResponseBody
@RequestMapping("/clear")
public String clear() {
cacheManager.getCache("ehcache").clear();
return "success";
}
接着,我们通过localhost:8080/clear访问来清除缓存后,再查询上面的那条数据,服务器将会报出不存在该记录的信息,至此,我们了解到了ehcahe缓存技术的使用,这也在项目的开发中经常使用。