缓存有一个缓存基类,其它缓存类都继承基类.去实现一些方法,其它缓存类可以在里面写自己特有的方法.以带到不同的需求.实现基类主要是方便管理缓存.
基类内容如下:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public abstract class BaseCache<T> {
/*
* 此Map将作为缓存的最大集合 它保存了所有子类对象中的数据(特殊的除外) 子类数据将以map集合存放
*/
static HashMap<String, HashMap<String,?>> _map = new HashMap<String, HashMap<String,?>>();
/**
* 此 集合主要用于 当我们在外部调用 执行把_map清空之后需要重新加载所有 初始化的数据的时候,用到此集合.
* 此集合保存了所有继承 此基类的 对象!所以在基类继承的时候 需要把基类对象保存在此集合
* (当然如果有一个方法可以返回 一个基类的所有子类就好了!)
*/
static List<BaseCache> _list = new ArrayList<BaseCache>();
protected void add(String key,HashMap<String,T> value){
_map.put(key, value);
}
protected void removre(String key){
_map.remove(key);
}
protected HashMap<String,T> getKey(String key){
return (HashMap<String,T>) _map.get(key);
}
protected static boolean containsKey(String key) {
return _map.containsKey(key);
}
/**
* 此方法 是通过 Map集合中的一个key 去获取 集合对象 避免了去通过 子类实例化之后去调用 getObject()的瓶颈
*
* 注:调用此方法之前请确保数据已经加载结束 否则抛出NullPointerException异常
*/
public List<T> getList(String key){
if (containsKey(key)) {
HashMap<String,T> l_map = getKey(key);
List<T> l_list = new ArrayList<T>();
for(T o:l_map.values())
l_list.add(o);
return l_list;
}else{
throw new NullPointerException();
}
}
/**
* 当外层使用此方法的时候 将调用子类的方法
* 子类将先调用父类的getKey()方法 查询是否存在此key,存在就直接返回
* 不存在就调用子类自己的数据加载方法
* @param key
* @return
*/
public abstract HashMap<String, T> getObject();
/**
* 用于刷新当前缓存 已达到数据同步
*/
public abstract void refresh();
/**
* 执行 所有 初始化数据加载
*/
public final static void loadAllData(){
for(BaseCache cache:_list)
cache.refresh();
}
}
再给一个实现类的例子:
import java.util.HashMap;
import com.xx.Atype;
public final class IAtypeCacheBean extends BaseCache<Atype> {
public static final String KEY = "atype";
static IAtypeCacheBean typeCache = new IAtypeCacheBean();
private IAtypeCacheBean() {
_list.add(typeCache); //添加基类对象
}
public static final synchronized IAtypeCacheBean getInit(){
if(typeCache==null)
typeCache = new IAtypeCacheBean();
typeCache.getObject();
return typeCache;
}
private final synchronized void addChannelCache() {
add(KEY, this.getlistP());
}
@Override
public HashMap<String, Atype> getObject() {
// TODO Auto-generated method stub
if (!containsKey(KEY)) {
addChannelCache();
}
HashMap<String, Atype> map = getKey(KEY);
return map;
}
@Override
public void refresh() {
// TODO Auto-generated method stub
addChannelCache();
}
private HashMap<String, Atype> getlistP(){
//这里获取 数据 处理 返回
return null ;
}
//----------子类可以扩展自己的方法 以达到不同需求
}
通过以上两个类,我相信你也会用了,下一部是数据加载类些好了,方法也有了,当然是项目启动的时候把数据加载到堆中去啊.
我想很多人应该是知道怎么写的, sservlet是可以在web.xml中进行配置成为加载类的.
import com.xx.BaseCache;
public class ConFigServlet extends HttpServlet {
public void init() throws ServletException {
//项目初始化加载数据
BaseCache.loadAllData();
}
}
Web.xml文件配置如下:
<servlet>
<servlet-name>loadDBSourceServlet</servlet-name>
<servlet-class>
com.xx.ConFigServlet //这是那个servlet的路径
</servlet-class>
<load-on-startup>2</load-on-startup> //这句很重要至于里面的数字写多少自己百度吧.
</servlet>
到这里,这一整套的方案出来了.就是使用了.因为java一切皆为对象,所以我们在往数据库插入一条数据之后我们只需要做一件事就是获取对应保存在缓存中的map ,然后把插入数据库的数据对象放入这个map里面,这样就也不用重新查询数据就达到了数据的同步.(删除也一样的原理 设计的时候用map的原因就是方便了 删 查)
到这里我就不说了提醒大家一下:在使用的时候一定要注意数据的同步.