首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

一个Hibernate缓冲署理的简单实现

2012-10-25 
一个Hibernate缓冲代理的简单实现??? 有的人很奇怪,Hibernate已经为我们提供了良好的缓存机制,还有必要在

一个Hibernate缓冲代理的简单实现

??? 有的人很奇怪,Hibernate已经为我们提供了良好的缓存机制,还有必要在应用程序的层面上进行缓存吗?这就好比CPU已经有了一级缓存,还要给它来个二级缓存,甚至还需要硬盘的缓存,光驱的缓存,总之,缓存无所不在,它们通常是比父一级的缓存机制更有针对性,更富有效率。

??? 和大多数人一样,不喜欢写太多的注释。下面的几个类要简单说明一下,其中的Department、Menu、Role等是几个被缓冲的类, CommonDao和PersistenceService是被封装的Hibernate数据操作类。在这里,CommonDao实例主要用来读数据, PersistenceService实例主要用来进行持久化。

??? 接下来就看看它是怎么实现的吧,有问题请大家多多指点。

java 代码?

  1. /**?
  2. ?*??
  3. ?*/??
  4. //package?com.company.project;??
  5. ??
  6. import?java.util.ArrayList;??
  7. import?java.util.HashMap;??
  8. import?java.util.List;??
  9. import?java.util.Map;??
  10. ??
  11. import?org.apache.commons.logging.Log;??
  12. import?org.apache.commons.logging.LogFactory;??
  13. ??
  14. import?com.etong.common.persistence.CommonDao;??
  15. import?com.etong.system.domain.Menu;??
  16. import?com.etong.system.domain.Role;??
  17. import?com.etong.system.service.PersistenceService;??
  18. import?com.etong.>
  19. ??????
  20. ????private?static?final?Log?log?=?LogFactory.getLog(HibernateBuffer.class);??
  21. ??????
  22. ????private?static?long?count;??
  23. ????private?static?HibernateBuffer?cache?=?null;??
  24. ????private?CommonDao?cdao?=?CommonDao.getInstance();??
  25. ????private?PersistenceService?ps?=?ServiceFactory.createPersistenceService();??????
  26. ??????
  27. ????private?int?objCount;??
  28. ????private?boolean[]?listChanged;??
  29. ????private?Map?cachedIndex;??
  30. ????private?Map[]?objMap;??
  31. ????private?List[]?objList;??
  32. ??????
  33. ????/**?
  34. ?????*?注册需要缓冲的类和对应的类获取ID的方法名称。?
  35. ?????*/??
  36. ????private?Class[]?objClass?=?{??
  37. ????????????Menu.class,???
  38. ????????????Role.class,??
  39. ??????????? Department.class??

  40. ????????};??
  41. ??????
  42. ????private?String[]?getIDMethod?=?{??
  43. ????????????"getMenuID",??
  44. ????????????"getRoleID",??
  45. ??????????? "getDeptId"??
  46. ????????};??
  47. ??????
  48. ????/**?
  49. ?????*?通过类反射和方法反射,将数据库中的对象初始化到相应的Map和List中?
  50. ?????*/??
  51. ????private?HibernateBuffer(){??
  52. ????????count?=?0;//计数器清零??
  53. ????????objCount?=?objClass.length;??
  54. ????????listChanged?=?new?boolean[objCount];??
  55. ????????cachedIndex?=?new?HashMap();??
  56. ????????objMap?=?new?HashMap[objCount];??
  57. ????????objList?=?new?ArrayList[objCount];??
  58. ??????????
  59. ????????for(int?i=0;i
  60. ????????????//将每个类对应的Index映射到Map中??
  61. ????????????cachedIndex.put(objClass[i],i);??
  62. ????????????objList[i]?=?cdao.findPersistenceObjects(objClass[i]);??
  63. ????????????objMap[i]?=?new?HashMap();??
  64. ????????????int?size?=?objList[i].size();??
  65. ????????????for(int?j=0;j
  66. ????????????????Object?obj?=?objList[i].get(j);??
  67. ????????????????try?{??
  68. ????????????????????Object?objID?=?obj.getClass().getMethod(getIDMethod[i],??
  69. ????????????????????????????new?Class[0]).invoke(obj,new?Object[]?{});??
  70. ????????????????????objMap[i].put(objID,?obj);??
  71. ????????????????}catch(Exception?e)?{??
  72. ????????????????????String?msg?=?"注册类"?+?objClass[i].getName()?+?"的方法"?+?getIDMethod[i]?+??
  73. ????????????????????????????"()调用时产生异常,可能是方法不存在或参数有误。";??
  74. ????????????????????log.error(msg, e);??
  75. ????????????????????throw?new?RuntimeException(msg);??
  76. ????????????????}??
  77. ????????????}??
  78. ????????????listChanged[i]?=?false;??
  79. ????????}??
  80. ????????if(log.isInfoEnabled())?{??
  81. ????????????StringBuffer?info?=?new?StringBuffer("已缓冲的类有:\n");??
  82. ????????????for(int?i=0;i
  83. ????????????????info.append("\t\t");??
  84. ????????????????info.append(objClass[i].getName());??
  85. ????????????}??
  86. ????????????log.info(info);??
  87. ????????}??
  88. ????}??
  89. ??
  90. ????/**?
  91. ?????*?获取Hibernate代理的一个共享实例?
  92. ?????*?@return?
  93. ?????*/??
  94. ????public?static?HibernateBuffer?getInstance()?{??
  95. ????????if(cache==null)?{??
  96. ????????????cache?=?new?HibernateBuffer();??
  97. ????????}??
  98. ????????if(log.isDebugEnabled())?{??
  99. ????????????log.debug("HibernateBuffer产生了第"?+?(++count)?+?"个共享实例");??
  100. ????????}??
  101. ????????return?cache;??
  102. ????}??
  103. ??
  104. ????private?int?getIndexByClass(Class?cls)?{??
  105. ????????Object?value?=?cachedIndex.get(cls);??
  106. ????????if(value==null)return?-1;
  107. ????????return?((Integer)value).intValue();??
  108. ????}??
  109. ??????
  110. ????/**?
  111. ?????*?从数据库中获取指定ID的对象实例。如果该实例不存在将抛出一个异常。?
  112. ?????*?@param?cls?
  113. ?????*?@param?id?
  114. ?????*?@return?
  115. ?????*/??
  116. ????public?Object?findPersistenceObjByID(Class?cls,?Long?id)?{??
  117. ????????int?index?=?getIndexByClass(cls);??
  118. ????????if(index<0)return?cdao.findPersistenceObjByID(cls,id);??
  119. ????????return?objMap[index].get(id);??
  120. ????}??
  121. ??????
  122. ????/**?
  123. ?????*?从数据库中获取指定ID的对象实例。如果该实例不存在将返回空。?
  124. ?????*?@param?cls?
  125. ?????*?@param?id?
  126. ?????*?@return?
  127. ?????*/??
  128. ????public?Object?getPersistenceObjByID(Class?cls,?Long?id)?{??
  129. ????????int?index?=?getIndexByClass(cls);??
  130. ????????if(index<0)return?cdao.getPersistenceObjByID(cls,?id);??
  131. ????????try?{??
  132. ????????????return?objMap[getIndexByClass(cls)].get(id);??
  133. ????????}catch(Exception?e)?{??
  134. ????????????return?null;??
  135. ????????}??
  136. ????}??
  137. ??????
  138. ????/**?
  139. ?????*?从数据库中获取指定对象的集合。?
  140. ?????*?@param?cls?
  141. ?????*?@return?
  142. ?????*/??
  143. ????public?List?findPersistenceObjects(Class?cls)?{??
  144. ????????int?index?=?getIndexByClass(cls);??
  145. ????????if(index<0)return?cdao.findPersistenceObjects(cls);??
  146. ????????if(listChanged[index])?{??
  147. ????????????objList[index]?=?cdao.findPersistenceObjects(cls);??
  148. ????????????listChanged[index]?=?false;??
  149. ????????}??
  150. ????????return?objList[index];??
  151. ????}??
  152. ??????
  153. ????/**?
  154. ?????*?持久化一个对象实例。?
  155. ?????*?@param?obj?
  156. ?????*/??
  157. ????public?void?makePersistent(Object?obj)?{??
  158. ????????//持久化后会使该对象自动获得一个ID??
  159. ????????ps.makePersistent(obj);??
  160. ????????int?index?=?getIndexByClass(obj.getClass());??
  161. ????????if(index<0)return;??
  162. ????????try?{??
  163. ????????????//获取持久化对象的ID,以便在objMap中建立缓冲。??
  164. ????????????Long?id?=?(Long)obj.getClass().getMethod(getIDMethod[index],?new?Class[0]).invoke(obj,new?Object[]?{});??
  165. ????????????objMap[index].put(id,?obj);??
  166. ????????????listChanged[index]?=?true;??
  167. ????????}catch(Exception?e)?{??
  168. ????????????String?msg?=?"注册类"?+?objClass[index].getName()?+?"的方法"?+?getIDMethod[index]?+??
  169. ????????????????????"()调用时产生异常,可能是方法不存在或参数有误。";??
  170. ????????????log.error(msg, e);??
  171. ????????????throw?new?RuntimeException(msg);??
  172. ????????}??
  173. ??
  174. ????}??
  175. ??????
  176. ????/**?
  177. ?????*?删除数据库中一个对象的全部实例。?
  178. ?????*?@param?cls?
  179. ?????*/??
  180. ????public?void?makeTransient(Class?cls)?{??
  181. ????????ps.makeTransient(cls);??
  182. ????????int?index?=?getIndexByClass(cls);??
  183. ????????if(index<0)return;??
  184. ????????objMap[index].clear();??
  185. ????????objList[index].clear();??
  186. ????????listChanged[index]?=?false;??
  187. ????}??
  188. ??????
  189. ????/**?
  190. ?????*?删除一个对象指定ID的实例?
  191. ?????*?@param?cls?
  192. ?????*?@param?id?
  193. ?????*/??
  194. ????public?void?makeTransient(Class?cls,?Long?id)?{??
  195. ????????ps.makeTransient(cls,id);??
  196. ????????int?index?=?getIndexByClass(cls);??
  197. ????????if(index<0)return;??
  198. ????????objMap[index].remove(id);??
  199. ????????listChanged[index]?=?true;??
  200. ????}??
  201. ??????
  202. ????/**?
  203. ?????*?删除一个对象一组指定ID的实例?
  204. ?????*?@param?cls?
  205. ?????*?@param?ids?
  206. ?????*/??
  207. ????public?void?makeTransient(Class?cls,?Long[]?ids)?{??
  208. ????????ps.makeTransient(cls,ids);??
  209. ????????int?index?=?getIndexByClass(cls);??
  210. ????????if(index<0)return;??
  211. ????????for(Long?id:ids)?{??
  212. ????????????objMap[index].remove(id);??
  213. ????????}??
  214. ????????listChanged[index]?=?true;??
  215. ????}??
  216. ??????
  217. ????/**?
  218. ?????*?一个简单的监视代理状态的方法。?
  219. ?????*/??
  220. ????public?static?void?monitor()?{??
  221. ????????new?Thread()?{??
  222. ????????????long?mins?=?0;??
  223. ????????????public?void?run()?{??
  224. ????????????????while(true)?{??
  225. ????????????????????try{??
  226. ????????????????????????Thread.sleep(60000);??
  227. ????????????????????????log.info("HibernateBuffer监控线程已运行"+(++mins)+"分钟,当前已产生"+count+"个共享实例");??
  228. ????????????????????}catch(InterruptedException?e){??
  229. ????????????????????????if(log.isInfoEnabled())?{??
  230. ????????????????????????????log.info("HibernateBuffer监控线程被中断……继续监控……");??
  231. ????????????????????????}??
  232. ????????????????????????mins++;??
  233. ????????????????????}??
  234. ????????????????}??
  235. ????????????}??
  236. ????????}.start();??
  237. ????}??
  238. ??????
  239. ????/**?
  240. ?????*?一个简单的用法示例。?
  241. ?????*?@param?args?
  242. ?????*/??
  243. ????public?static?void?main(String[]?args)?{??
  244. ????????monitor();??
  245. ????????HibernateBuffer?hb?=?HibernateBuffer.getInstance();??
  246. ??????????
  247. ????????//查询一个Department实例??
  248. ????????Department?dept?=?(Department)hb.findPersistenceObjByID(Department.class,?1L);??
  249. ????????System.out.println(dept.getName());??
  250. ??????????
  251. ????????//持久化一个Department实例??
  252. ????????dept?=?new?Department();??
  253. ????????dept.setName("金融科");??
  254. ????????dept.setNumber("007");??
  255. ????????hb.makePersistent(dept);??
  256. ??????????
  257. ????????//查询全部Department实例的集合??
  258. ????????List?deptList?=?hb.findPersistenceObjects(Department.class);??
  259. ????????System.out.println(deptList.size());??
  260. ??????????
  261. ????????//删除金融科??
  262. ????????hb.makeTransient(Department.class,?dept.getDepartmentID());??
  263. ??????????
  264. ????????//再次查询Department实例的集合??
  265. ????????deptList?=?hb.findPersistenceObjects(Department.class);??
  266. ????????System.out.println(deptList.size());??
  267. ????}??
  268. }??
1 楼 SunMicro 2007-01-20   以目前的水平,看注释较少的代码的确比较吃力,汗!lz通过java容器储存被持久化的实例来实现缓寸,那不是每执行一次makePersistent方法,如果是被注册类的实例就会增大缓存,似乎没有设定缓存的大小,这样的话,若不手工清除,缓存不是会随操作次数的增加而一直增大?

   由于看得不是太懂,不知道是不是我有什么地方没有理解到。希望lz能赐教! 2 楼 xifo 2007-01-21   SunMicro 写道以目前的水平,看注释较少的代码的确比较吃力,汗!lz通过java容器储存被持久化的实例来实现缓寸,那不是每执行一次makePersistent方法,如果是被注册类的实例就会增大缓存,似乎没有设定缓存的大小,这样的话,若不手工清除,缓存不是会随操作次数的增加而一直增大?

   由于看得不是太懂,不知道是不是我有什么地方没有理解到。希望lz能赐教!使用这个实现的初衷是,对于数据库中常用的表,避免每次从数据库中Select出来,而是在第一次使用时载入内存,本质上与很多人将一些常用表放到application中类似,只是不需要从application中解析,而是和别的没有缓存的表一样,按照统一的方式进行存取。 3 楼 xifo 2007-07-14   看自己一年前的代码,总是有种说不出的别扭。

看现在很多人写的代码,也是说不出的难受。是不是开源的东西看得太多了? 4 楼 Godlikeme 2007-07-14   粗略的看了下,没有看到任何同步的处理,和并发的测试,是这个样子的么?

热点排行