项目中使用Ehcache技术
- 导入jar包
- 配置Ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!-- 缓存数据溢出时钝化【数据从内存转移到磁盘】到磁盘路径 -->
<diskStore path="C:/ehcache"/>
<!--
一个cache标签表示一个缓存对象
一般情况下,数据库中的每张表都对应这样一个cache标签【针对每张表的数据单独进行缓存】
一个cache标签就会在C:/ehcache目录下生成一个缓存文件
name:表示cache标签的名称,可以通过这个名称获取到一个Cache对象
maxElementsInMemory:内存最多允许缓存多少数据量【适量即可】
eternal:缓存数据是否永久存活
overflowToDisk:是否允许溢出到磁盘【内存中数据量超过maxElementsInMemory配置的数据量】
maxElementsOnDisk:磁盘上最多允许保存多少条数据【domain实体对象】尽量设置大一点
-->
<cache
name="addressCache"
maxElementsInMemory="1"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<cache
name="carouselCache"
maxElementsInMemory="1"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<cache
name="jobCache"
maxElementsInMemory="1"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
</ehcache>
- 创建Ehcache工具类
package cn.itsource.utils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import cn.itsource.domain.Address;
import cn.itsource.ibase.IBaseDao;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
public class EhcacheUtil {
/**
* 封装的缓存获取数据方法
* 当缓存中没有目标数据时调用dao层对象的方法去查询数据,并且添加到缓存中。
* @param cm 缓存管理器
* @param cacheName cache标签的name属性值
* @param dataKey 数据保存到缓存中的key
* @param dao 当缓存中没有目标数据时调用此对象的方法去查询数据
* @param methodName 当缓存中没有目标数据时调用此对象的此方法去查询数据
* @param params 当缓存中没有目标数据时调用此对象的此方法去查询数据时要传入的实参
* @return 从缓存中获取到的数据
*/
public static <T> Object getCacheData(CacheManager cm, String cacheName, String dataKey,
IBaseDao<T> dao, String methodName, Object... params){
for (Object object : params) {
System.out.println("++++++"+object);
}
//判断是否取到
Object data = null;
try {
//获取字节码对象
Class<? extends IBaseDao> cls = dao.getClass();
Cache cache = cm.getCache(cacheName);
//原理[先到缓存中去获取数据]
Element element = cache.get(dataKey);
Method method = null;
if(null == element){
//没取到就查询【使用反射来调用dao对象的某个方法】
if("loadEntitys".equals(methodName)){
if(params[0] instanceof Condition){
method = cls.getMethod(methodName, Condition.class);
data = method.invoke(dao, params[0]);
}else{
method = cls.getMethod(methodName, Object[].class);
data = method.invoke(dao, (Object)params);
}
}else if("loadById".equals(methodName)){
method = cls.getMethod(methodName, String.class);
data = method.invoke(dao, params[0]);
}else if("loadCount".equals(methodName)){
method = cls.getMethod(methodName, Condition.class);
data = method.invoke(dao, params[0]);
}
//再缓存
cache.put(new Element(dataKey, data));
}else{
//取到了
data = element.getObjectValue();
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (ClassCastException e) {
e.printStackTrace();
} catch (CacheException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return data;
}
}
要记得修改所有已写Service层的实现类中的查询方法,使用编写的EhcacheUtil工具。
而且增删改数据之后要清空原先缓存。