項目中使用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工具。
而且增刪改數據之後要清空原先緩存。