- xifo
- 等级: 初级会员
- 性别:
- 文章: 30
- 积分: 43
- 来自: 安徽
|
有的人很奇怪,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代理,
-
- * Copyright: Copyright (c) 2006
- * Company: ××信息技术有限公司
- * Created on Jun 16, 2006
-
-
-
-
- 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;
-
-
-
-
- private Class[] objClass = {
- Menu.class,
- Role.class,
-
Department.class
- };
-
- private String[] getIDMethod = {
- "getMenuID",
- "getRoleID",
- "getDeptId"
- };
-
-
-
-
- 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
-
- 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);
- }
- }
-
-
-
-
-
- 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();
- }
-
-
-
-
-
-
-
- public Object findPersistenceObjByID(Class cls, Long id) {
- int index = getIndexByClass(cls);
- if(index<0)return cdao.findPersistenceObjByID(cls,id);
- return objMap[index].get(id);
- }
-
-
-
-
-
-
-
- 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;
- }
- }
-
-
-
-
-
-
- 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];
- }
-
-
-
-
-
- public void makePersistent(Object obj) {
-
- ps.makePersistent(obj);
- int index = getIndexByClass(obj.getClass());
- if(index<0)return;
- try {
-
- 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);
- }
-
- }
-
-
-
-
-
- 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;
- }
-
-
-
-
-
-
- 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;
- }
-
-
-
-
-
-
- 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();
- }
-
-
-
-
-
- public static void main(String[] args) {
- monitor();
- HibernateBuffer hb = HibernateBuffer.getInstance();
-
-
- Department dept = (Department)hb.findPersistenceObjByID(Department.class, 1L);
- System.out.println(dept.getName());
-
-
- dept = new Department();
- dept.setName("金融科");
- dept.setNumber("007");
- hb.makePersistent(dept);
-
-
- List deptList = hb.findPersistenceObjects(Department.class);
- System.out.println(deptList.size());
-
-
- hb.makeTransient(Department.class, dept.getDepartmentID());
-
-
- deptList = hb.findPersistenceObjects(Department.class);
- System.out.println(deptList.size());
- }
- }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
返回顶楼 |
|
|
- SunMicro
- 等级:
- 文章: 197
- 积分: 399
|
以目前的水平,看注释较少的代码的确比较吃力,汗!lz通过java容器储存被持久化的实例来实现缓寸,那不是每执行一次makePersistent方法,如果是被注册类的实例就会增大缓存,似乎没有设定缓存的大小,这样的话,若不手工清除,缓存不是会随操作次数的增加而一直增大?
由于看得不是太懂,不知道是不是我有什么地方没有理解到。希望lz能赐教!
|
返回顶楼 |
|
|
- xifo
- 等级: 初级会员
- 性别:
- 文章: 30
- 积分: 43
- 来自: 安徽
|
SunMicro 写道 以目前的水平,看注释较少的代码的确比较吃力,汗!lz通过java容器储存被持久化的实例来实现缓寸,那不是每执行一次makePersistent方法,如果是被注册类的实例就会增大缓存,似乎没有设定缓存的大小,这样的话,若不手工清除,缓存不是会随操作次数的增加而一直增大?
由于看得不是太懂,不知道是不是我有什么地方没有理解到。希望lz能赐教! 使用这个实现的初衷是,对于数据库中常用的表,避免每次从数据库中Select出来,而是在第一次使用时载入内存,本质上与很多人将一些常用表放到application中类似,只是不需要从application中解析,而是和别的没有缓存的表一样,按照统一的方式进行存取。
|
返回顶楼 |
|
|
- xifo
- 等级: 初级会员
- 性别:
- 文章: 30
- 积分: 43
- 来自: 安徽
|
看自己一年前的代码,总是有种说不出的别扭。
看现在很多人写的代码,也是说不出的难受。是不是开源的东西看得太多了?
|
返回顶楼 |
|
|
- Godlikeme
- 等级:
- 性别:
- 文章: 1159
- 积分: 744
- 来自: 北京
|
粗略的看了下,没有看到任何同步的处理,和并发的测试,是这个样子的么?
|
返回顶楼 |
|
|