有的人很奇怪,Hibernate已经为我们提供了良好的缓存机制,还有必要在应用程序的层面上进行缓存吗?这就好比CPU已经有了一级缓存,还要给它来个二级缓存,甚至还需要硬盘的缓存,光驱的缓存,总之,缓存无所不在,它们通常是比父一级的缓存机制更有针对性,更富有效率。
和大多数人一样,不喜欢写太多的注释。下面的几个类要简单说明一下,其中的Department、Menu、Role等是几个被缓冲的类, CommonDao和PersistenceService是被封装的Hibernate数据操作类。在这里,CommonDao实例主要用来读数据, PersistenceService实例主要用来进行持久化。
接下来就看看它是怎么实现的吧,有问题请大家多多指点。
java 代码
- /**
- *
- */
- //package com.company.project;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import com.etong.common.persistence.CommonDao;
- import com.etong.system.domain.Menu;
- import com.etong.system.domain.Role;
- import com.etong.system.service.PersistenceService;
- import com.etong.system.service.ServiceFactory;
- /**
- * Title: Hibernate的一个读写缓冲代理
- * Description: 一个CommonDao和PersistenceService代理,
- * 对于经常从数据库中存取的类,可以在数组中进行注册,
- * 该缓冲器将用Map,List等形式,缓冲存取的对象和集合。
- * Copyright: Copyright (c) 2006
- * Company: ××信息技术有限公司
- * Created on Jun 16, 2006
- * @author xifo
- * @version 1.0
- *
- */
- public class HibernateBuffer {
- private static final Log log = LogFactory.getLog(HibernateBuffer.class);
- private static long count;
- private static HibernateBuffer cache = null;
- private CommonDao cdao = CommonDao.getInstance();
- private PersistenceService ps = ServiceFactory.createPersistenceService();
- private int objCount;
- private boolean[] listChanged;
- private Map cachedIndex;
- private Map[] objMap;
- private List[] objList;
- /**
- * 注册需要缓冲的类和对应的类获取ID的方法名称。
- */
- private Class[] objClass = {
- Menu.class,
- Role.class,
-
Department.class
- };
- private String[] getIDMethod = {
- "getMenuID",
- "getRoleID",
- "getDeptId"
- };
- /**
- * 通过类反射和方法反射,将数据库中的对象初始化到相应的Map和List中
- */
- private HibernateBuffer(){
- count = 0;//计数器清零
- objCount = objClass.length;
- listChanged = new boolean[objCount];
- cachedIndex = new HashMap();
- objMap = new HashMap[objCount];
- objList = new ArrayList[objCount];
- for(int i=0;i
- //将每个类对应的Index映射到Map中
- cachedIndex.put(objClass[i],i);
- objList[i] = cdao.findPersistenceObjects(objClass[i]);
- objMap[i] = new HashMap();
- int size = objList[i].size();
- for(int j=0;j
- Object obj = objList[i].get(j);
- try {
- Object objID = obj.getClass().getMethod(getIDMethod[i],
- new Class[0]).invoke(obj,new Object[] {});
- objMap[i].put(objID, obj);
- }catch(Exception e) {
- String msg = "注册类" + objClass[i].getName() + "的方法" + getIDMethod[i] +
- "()调用时产生异常,可能是方法不存在或参数有误。";
- log.error(msg, e);
- throw new RuntimeException(msg);
- }
- }
- listChanged[i] = false;
- }
- if(log.isInfoEnabled()) {
- StringBuffer info = new StringBuffer("已缓冲的类有:\n");
- for(int i=0;i
- info.append("\t\t");
- info.append(objClass[i].getName());
- }
- log.info(info);
- }
- }
- /**
- * 获取Hibernate代理的一个共享实例
- * @return
- */
- public static HibernateBuffer getInstance() {
- if(cache==null) {
- cache = new HibernateBuffer();
- }
- if(log.isDebugEnabled()) {
- log.debug("HibernateBuffer产生了第" + (++count) + "个共享实例");
- }
- return cache;
- }
- private int getIndexByClass(Class cls) {
- Object value = cachedIndex.get(cls);
- if(value==null)return -1;
- return ((Integer)value).intValue();
- }
- /**
- * 从数据库中获取指定ID的对象实例。如果该实例不存在将抛出一个异常。
- * @param cls
- * @param id
- * @return
- */
- public Object findPersistenceObjByID(Class cls, Long id) {
- int index = getIndexByClass(cls);
- if(index<0)return cdao.findPersistenceObjByID(cls,id);
- return objMap[index].get(id);
- }
- /**
- * 从数据库中获取指定ID的对象实例。如果该实例不存在将返回空。
- * @param cls
- * @param id
- * @return
- */
- public Object getPersistenceObjByID(Class cls, Long id) {
- int index = getIndexByClass(cls);
- if(index<0)return cdao.getPersistenceObjByID(cls, id);
- try {
- return objMap[getIndexByClass(cls)].get(id);
- }catch(Exception e) {
- return null;
- }
- }
- /**
- * 从数据库中获取指定对象的集合。
- * @param cls
- * @return
- */
- public List findPersistenceObjects(Class cls) {
- int index = getIndexByClass(cls);
- if(index<0)return cdao.findPersistenceObjects(cls);
- if(listChanged[index]) {
- objList[index] = cdao.findPersistenceObjects(cls);
- listChanged[index] = false;
- }
- return objList[index];
- }
- /**
- * 持久化一个对象实例。
- * @param obj
- */
- public void makePersistent(Object obj) {
- //持久化后会使该对象自动获得一个ID
- ps.makePersistent(obj);
- int index = getIndexByClass(obj.getClass());
- if(index<0)return;
- try {
- //获取持久化对象的ID,以便在objMap中建立缓冲。
- Long id = (Long)obj.getClass().getMethod(getIDMethod[index], new Class[0]).invoke(obj,new Object[] {});
- objMap[index].put(id, obj);
- listChanged[index] = true;
- }catch(Exception e) {
- String msg = "注册类" + objClass[index].getName() + "的方法" + getIDMethod[index] +
- "()调用时产生异常,可能是方法不存在或参数有误。";
- log.error(msg, e);
- throw new RuntimeException(msg);
- }
- }
- /**
- * 删除数据库中一个对象的全部实例。
- * @param cls
- */
- public void makeTransient(Class cls) {
- ps.makeTransient(cls);
- int index = getIndexByClass(cls);
- if(index<0)return;
- objMap[index].clear();
- objList[index].clear();
- listChanged[index] = false;
- }
- /**
- * 删除一个对象指定ID的实例
- * @param cls
- * @param id
- */
- public void makeTransient(Class cls, Long id) {
- ps.makeTransient(cls,id);
- int index = getIndexByClass(cls);
- if(index<0)return;
- objMap[index].remove(id);
- listChanged[index] = true;
- }
- /**
- * 删除一个对象一组指定ID的实例
- * @param cls
- * @param ids
- */
- public void makeTransient(Class cls, Long[] ids) {
- ps.makeTransient(cls,ids);
- int index = getIndexByClass(cls);
- if(index<0)return;
- for(Long id:ids) {
- objMap[index].remove(id);
- }
- listChanged[index] = true;
- }
- /**
- * 一个简单的监视代理状态的方法。
- */
- public static void monitor() {
- new Thread() {
- long mins = 0;
- public void run() {
- while(true) {
- try{
- Thread.sleep(60000);
- log.info("HibernateBuffer监控线程已运行"+(++mins)+"分钟,当前已产生"+count+"个共享实例");
- }catch(InterruptedException e){
- if(log.isInfoEnabled()) {
- log.info("HibernateBuffer监控线程被中断……继续监控……");
- }
- mins++;
- }
- }
- }
- }.start();
- }
- /**
- * 一个简单的用法示例。
- * @param args
- */
- public static void main(String[] args) {
- monitor();
- HibernateBuffer hb = HibernateBuffer.getInstance();
- //查询一个Department实例
- Department dept = (Department)hb.findPersistenceObjByID(Department.class, 1L);
- System.out.println(dept.getName());
- //持久化一个Department实例
- dept = new Department();
- dept.setName("金融科");
- dept.setNumber("007");
- hb.makePersistent(dept);
- //查询全部Department实例的集合
- List deptList = hb.findPersistenceObjects(Department.class);
- System.out.println(deptList.size());
- //删除金融科
- hb.makeTransient(Department.class, dept.getDepartmentID());
- //再次查询Department实例的集合
- deptList = hb.findPersistenceObjects(Department.class);
- System.out.println(deptList.size());
- }
- }