中国高校大约2000多所学校,学校的基本信息一般不会改变。
用户常见的操作会有查看学校的基本信息,以及分数的查询。假如每次都到数据库中取得学校的数据,是没有必要的,而且从数据库中取得数据的速度慢,怎么办呢?缓存应运而生。
从网上大量的资料来看,大家普遍的都用encache框架来做缓存,没有什么好说的,研究研究她吧。
encache的特性:
1. 快速.
2. 简单.
3. 多种缓存策略
4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题
5. 缓存数据会在虚拟机重启的过程中写入磁盘
6. 可以通过RMI、可插入API等方式进行分布式缓存
7. 具有缓存和缓存管理器的侦听接口
8. 支持多缓存管理器实例,以及一个实例的多个缓存区域
9. 提供Hibernate的缓存实现
具体代码架构图:
0、首先加入ehcache-core-1.7.2.jar
1、Cache.java
package com.xing.core.cache; import java.util.List; /** * Implementors define a caching algorithm. All implementors * <b>must</b> be threadsafe. */ public interface Cache { /** * Get an item from the cache, nontransactionally * @param key * @return the cached object or <tt>null</tt> * @throws CacheException */ public Object get(Object key) throws CacheException; /** * Add an item to the cache, nontransactionally, with * failfast semantics * @param key * @param value * @throws CacheException */ public void put(Object key, Object value) throws CacheException; /** * Add an item to the cache * @param key * @param value * @throws CacheException */ public void update(Object key, Object value) throws CacheException; @SuppressWarnings("rawtypes") public List keys() throws CacheException ; /** * Remove an item from the cache */ public void remove(Object key) throws CacheException; /** * Clear the cache */ public void clear() throws CacheException; /** * Clean up */ public void destroy() throws CacheException; }2CacheException.java
package com.xing.core.cache; /** * Something went wrong in the cache */ public class CacheException extends RuntimeException { private static final long serialVersionUID = -3044257085401548929L; public CacheException(String s) { super(s); } public CacheException(String s, Throwable e) { super(s, e); } public CacheException(Throwable e) { super(e); } }3 CacheManager.java
package com.xing.core.cache; import java.io.Serializable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 缓存助手 */ public class CacheManager { private final static Log log = LogFactory.getLog(CacheManager.class); private static CacheProvider provider; public static void init(String prv_name){ try{ CacheManager.provider = (CacheProvider)Class.forName(prv_name).newInstance(); CacheManager.provider.start(); }catch(Exception e){ log.fatal("Unabled to initialize cache provider:" + prv_name + ", using ehcache default.", e); CacheManager.provider = new EhCacheProvider(); } } private final static Cache _getCache(String cache_name) { if(provider == null){ provider = new EhCacheProvider(); provider.start(); } return provider.buildCache(cache_name); } /** * 获取缓存中的数据 * @param name 缓存名 * @param key * @return */ public final static Object get(String name, Serializable key){ if(name!=null && key != null) return _getCache(name).get(key); return null; } /** * 获取缓存中的数据 * @param <T> * @param resultClass * @param name * @param key * @return */ @SuppressWarnings("unchecked") public final static <T> T get(Class<T> resultClass, String name, Serializable key){ if(name!=null && key != null) return (T)_getCache(name).get(key); return null; } /** * 写入缓存 * @param name * @param key * @param value */ public final static void set(String name, Serializable key, Serializable value){ if(name!=null && key != null && value!=null) _getCache(name).put(key, value); } /** * 清除缓冲中的某个数据 * @param name * @param key */ public final static void evict(String name, Serializable key){ if(name!=null && key != null) _getCache(name).remove(key); } }4 CacheProvider.java
package com.xing.core.cache; /** * Support for pluggable caches. */ public interface CacheProvider { /** * Configure the cache * * @param regionName the name of the cache region * @param properties configuration settings * @throws CacheException */ public Cache buildCache(String regionName) throws CacheException; /** * Callback to perform any necessary initialization of the underlying cache implementation * during SessionFactory construction. * * @param properties current configuration settings. */ public void start() throws CacheException; /** * Callback to perform any necessary cleanup of the underlying cache implementation * during SessionFactory.close(). */ public void stop(); }5 EhCache.java
//$Id: EhCache.java 10716 2006-11-03 19:05:11Z [email protected] $ /** * Copyright 2003-2006 Greg Luck, Jboss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.xing.core.cache; import java.util.List; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; /** * EHCache */ public class EhCache implements Cache { private net.sf.ehcache.Cache cache; /** * Creates a new Hibernate pluggable cache based on a cache name. * <p/> * * @param cache The underlying EhCache instance to use. */ public EhCache(net.sf.ehcache.Cache cache) { this.cache = cache; } @SuppressWarnings("rawtypes") public List keys() throws CacheException { return this.cache.getKeys(); } /** * Gets a value of an element which matches the given key. * * @param key the key of the element to return. * @return The value placed into the cache with an earlier put, or null if not found or expired * @throws CacheException */ public Object get(Object key) throws CacheException { try { if ( key == null ) return null; else { Element element = cache.get( key ); if ( element != null ) return element.getObjectValue(); } return null; } catch (net.sf.ehcache.CacheException e) { throw new CacheException( e ); } } /** * Puts an object into the cache. * * @param key a key * @param value a value * @throws CacheException if the {@link CacheManager} * is shutdown or another {@link Exception} occurs. */ public void update(Object key, Object value) throws CacheException { put( key, value ); } /** * Puts an object into the cache. * * @param key a key * @param value a value * @throws CacheException if the {@link CacheManager} * is shutdown or another {@link Exception} occurs. */ public void put(Object key, Object value) throws CacheException { try { Element element = new Element( key, value ); cache.put( element ); } catch (IllegalArgumentException e) { throw new CacheException( e ); } catch (IllegalStateException e) { throw new CacheException( e ); } catch (net.sf.ehcache.CacheException e) { throw new CacheException( e ); } } /** * Removes the element which matches the key. * <p/> * If no element matches, nothing is removed and no Exception is thrown. * * @param key the key of the element to remove * @throws CacheException */ public void remove(Object key) throws CacheException { try { cache.remove( key ); } catch (IllegalStateException e) { throw new CacheException( e ); } catch (net.sf.ehcache.CacheException e) { throw new CacheException( e ); } } /** * Remove all elements in the cache, but leave the cache * in a useable state. * * @throws CacheException */ public void clear() throws CacheException { try { cache.removeAll(); } catch (IllegalStateException e) { throw new CacheException( e ); } catch (net.sf.ehcache.CacheException e) { throw new CacheException( e ); } } /** * Remove the cache and make it unuseable. * * @throws CacheException */ public void destroy() throws CacheException { try { cache.getCacheManager().removeCache( cache.getName() ); } catch (IllegalStateException e) { throw new CacheException( e ); } catch (net.sf.ehcache.CacheException e) { throw new CacheException( e ); } } }6 EhCacheProvider.java
//$Id: EhCacheProvider.java 9964 2006-05-30 15:40:54Z epbernard $ /** * Copyright 2003-2006 Greg Luck, Jboss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.xing.core.cache; import java.util.Hashtable; import net.sf.ehcache.CacheManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Cache Provider plugin * * Taken from EhCache 1.3 distribution */ public class EhCacheProvider implements CacheProvider { private static final Log log = LogFactory.getLog(EhCacheProvider.class); private CacheManager manager; private Hashtable<String, EhCache> _cacheManager ; /** * Builds a Cache. * <p> * Even though this method provides properties, they are not used. * Properties for EHCache are specified in the ehcache.xml file. * Configuration will be read from ehcache.xml for a cache declaration * where the name attribute matches the name parameter in this builder. * * @param name the name of the cache. Must match a cache configured in ehcache.xml * @param properties not used * @return a newly built cache will be built and initialised * @throws CacheException inter alia, if a cache of the same name already exists */ public EhCache buildCache(String name) throws CacheException { EhCache ehcache = _cacheManager.get(name); if(ehcache != null) return ehcache ; try { net.sf.ehcache.Cache cache = manager.getCache(name); if (cache == null) { log.warn("Could not find configuration [" + name + "]; using defaults."); manager.addCache(name); cache = manager.getCache(name); log.debug("started EHCache region: " + name); } synchronized(_cacheManager){ ehcache = new EhCache(cache); _cacheManager.put(name, ehcache); return ehcache ; } } catch (net.sf.ehcache.CacheException e) { throw new CacheException(e); } } /** * Callback to perform any necessary initialization of the underlying cache implementation * during SessionFactory construction. * * @param properties current configuration settings. */ public void start() throws CacheException { if (manager != null) { log.warn("Attempt to restart an already started EhCacheProvider. Use sessionFactory.close() " + " between repeated calls to buildSessionFactory. Using previously created EhCacheProvider." + " If this behaviour is required, consider using net.sf.ehcache.hibernate.SingletonEhCacheProvider."); return; } manager = new CacheManager(); _cacheManager = new Hashtable<String, EhCache>(); } /** * Callback to perform any necessary cleanup of the underlying cache implementation * during SessionFactory.close(). */ public void stop() { if (manager != null) { manager.shutdown(); manager = null; } } }7 ICacheHelper.java
package com.xing.core.cache; import java.io.Serializable; import java.util.List; import java.util.Vector; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 自动缓存数据重加载 * @author Winter Lau */ public class ICacheHelper { private static final Log log = LogFactory.getLog(ICacheHelper.class); final static CacheUpdater g_ThreadPool = new CacheUpdater(); static class CacheUpdater extends ThreadPoolExecutor { private List<String> runningThreadNames = new Vector<String>(); public CacheUpdater() { super(0, 20, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20), new ThreadPoolExecutor.DiscardOldestPolicy()); } public void execute(Thread command) { if(runningThreadNames.contains(command.getName())){ log.warn(command.getName() + " ===================> Running."); return ; } log.info(command.getName() + " ===================> Started."); super.execute(command); } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); Thread thread = (Thread)r; runningThreadNames.remove(thread.getName()); log.info(thread.getName() + " ===================> Finished."); } } private final static String CACHE_GLOBAL = "icache-global"; /** * 获取缓存数据 * @param region * @param key * @param invoker * @param args * @return */ public static Object get(final String region, final Serializable key, final ICacheInvoker invoker, final Object... args) { //1. 从正常缓存中获取数据 Object data = CacheManager.get(region, key); if(data == null) { final String global_key = key + "@" + region; //2. 从全局二级缓存中获取数据 data = CacheManager.get(CACHE_GLOBAL, global_key); //2.1 取不到为第一次运行 if(data == null){ if(invoker != null) { data = invoker.callback(args); if(data != null){ CacheManager.set(region, key, (Serializable)data); CacheManager.set(CACHE_GLOBAL, global_key, (Serializable)data); } } } //2.2 如果取到了则执行自动更新数据策略 else if(invoker != null) { String thread_name = "CacheUpdater-" + region + "-" + key; //g_ThreadPool.execute( new Thread(thread_name){ public void run(){ Object result = invoker.callback(args); if(result != null){ CacheManager.set(region, key, (Serializable)result); CacheManager.set(CACHE_GLOBAL, global_key, (Serializable)result); } } }.start(); //); } } return data; } }8 ICacheInvoker.java
/** * */ package com.xing.core.cache; /** * 回调接口 * @author Winter Lau */ public interface ICacheInvoker { public Object callback(Object...args) ; }
9 测试类TestEnCache.java
package com.xing.core.cache; public class TestEnCache { /** * @param args */ public static void main(String[] args) { String cacheName="cacheA"; String key="邯郸学院"; String value="很好啊"; //set(cacheName, key, value); String gValue = (String)CacheManager.get(cacheName, key);//A if(gValue!=null){ System.out.println("获取缓存成功:"+gValue); }else{ System.out.println("获取缓存为空,设置缓存"); CacheManager.set(cacheName, key, value); System.out.println("设置缓存之后获取缓存:"+(String)CacheManager.get(cacheName, key)); } } }
开始我很疑惑,我没有设置缓存文件ehcache.xml,他是怎么设置进去的啊?并且读到里面的数据呢?