绝大部分情况,使用缓存对效率提升来说是一个非常大的性能提升,但在这种性能提升的背景,缓存数据是否有效,能否支持通知更新,缓存是否支持集群分布式这些问题是作为系统设计环节中必须要考虑的。
大家知道,ibatis对oscache提供了很好的支持,在更新刷新缓存,支持集群方面做的还算是令人满意。平时开发过程中也会遇到一些非SQL查询缓存需求,如登录用户部分登录处理过后信息需要能够被及时缓存起来,这是一个面向于一个用户级缓存,缓存范围非session会话级别的。如果数据库相关数据变动后,又需要对这些缓存数据进行通知更新。为了解决这个问题,我们可以使用两种办法:
1、 对缓存的数据通过SQL语句查询搞定,在OSCACHE缓存策略上进行刷新策略配置;
2、 直接使用OSCACHE中缓存刷新策略,对内存对象数据直接保存;
对与方法1,是基于ibatis本身对sql缓存的机制实现,但这样的实现是基于SQL形式,如果缓存数据不是能很好通过SQL查询结果时,还是存在一定的限制性。为了脱离SQL缓存,找出一种直接缓存,又可以得到相关数据变动更新的办法,我们就需要采用方法2。
针对于方法2中可以直接使用ibatis中oscache缓存,又可以采取数据变更通知。我的原理很简单,在一个jvm中,直接找到ibatis的oscache引用来实现自定义数据缓存。根据这种思路,我们查看一下ibatis中oscache引用代码com.ibatis.sqlmap.engine.cache.oscache. OSCacheController。看到下面OSCacheController代码红色部分,oscache被应用成静态private变量了,还是final,这样更好,反正我们不会去改他的引用,并且这个对象在jvm中就只有一份。大家注意在看flush代码,通过debug实践,可以得出他就是我们缓存更新策略生效时会调用的清理缓存方法,这点很重要,基于这个机制,是实现后面自定义缓存的关键部分。
接下来的事情很简单,看下面staitc代码部分,利用反射的机制,在jvm中取到OSCacheController.CACHE成员变量的引用,即使它是private,但是在sun公司的合法规范下,还是都能获取的到。:)获取到引用后,我们根据官方的接口也实现一下putObject、getObject、removeObject方法,只是这些方法中我们不在使用ibatis官方的CacheModel缓存对象了,使得方法变得更加简单。注意,我们提供的putObject方法带有cacheId参数,这个参数很重要,根据上面我们提到的官方缓存更新策略生效时,会调用flush方法的原理,我们在缓存自定义数据的同时,一定要指明我们需要使用缓存刷新策略的id是多少。因为通过反射机制,我们拿到了OSCacheController的CACHE引用,CACHE又是静态变量,我们缓存的数据和ibatis本身的缓存数据是用的同一个oacache,并且它更新缓存策略时,我拿过来的oscache对象也会同时更新。
接下来我们做个例子,我们BIAP集成系统管理平台提高了统一的集成应用展现框架,并且在用户登录的时候动态去生成用户有权限访问的菜单,菜单是通过登录用户权限信息生成的html字符,生成过程较为耗时。在登录过程中,我们已经对登录相关的查询都进行了ibatis缓存,更新策略如下:
登录代码里我们改动一下组装菜单部分的代码,缓存的key我们使用固定常量CACHE_MENU+用户登录id。在绿色部分先去判断缓存中有没有,处理好的菜单数据,没有的话我们通过调用私有menuProcess(operator)方法处理菜单,并且在下列红色代码部分中,将处理好的菜单数据menu放置在缓存中,并且使用常量CACHE_ID,CACHE_ID值为sysLogin.operator-cache,对没错,就是我们更新策略中SqlMap的namespace+cacheModel的id组合。
接下来我们debug看看效果。第一次登录,从缓存中没有取到登录者的菜单处理数据。
我们将菜单处理后的数据,保存在oscache缓存中。
第二次登录,找到了我们之前的为该用户缓存的数据
我们来修改菜单来检查是否能更具缓存更新策略更新我们的缓存
用debug模式可以观测到GeneralCacheAdministrator中我们的sysLogin.operator-cache更新策略已经被调用。
第三次登录,恭喜,我们的缓存已经接到更新策略执行了清除。我们就不用担心缓存数据中的数据过时了。
总结:我们通过观察官方源码得知ibatis中缓存刷新机制和缓存使用机制,再利用合理规范的反射技术来获取jvm中ibatis使用的oscache对象,按照ibatis的刷新规范在缓存时保存选择使用缓存刷新策略,从而实现了我们自定义缓存和缓存动态更新的功能。重要的不在于大家对这功能的掌握,更关键的是对缓存设计思路的理解。
原创文章,如果转载,请标注作者:田文 CSDN地址:http://blog.csdn.net/tiwen818
- 大小: 61.7 KB
- 大小: 47.6 KB
- 大小: 61.6 KB
- 大小: 83 KB
- 大小: 47.7 KB
- 大小: 78.1 KB
分享到:
相关推荐
ibatis 数据缓存,帮你了解ibatis的数据缓存机制。
如何解决动态数据表名,动态字段名情况下,由ibatis缓存select字段而引起的字段找不到的情况?以下是最简单的解决办法! 本文中内容真实可靠,保证用户很快掌握
iBATIS缓存介绍 iBATIS二级缓存 iBATIS缓存配置
iBATIS缓存的使用方法
ibatis实现原理解析
ibatis缓存介绍 - 勇泽 - 博客园ibatis缓存介绍 - 勇泽 - 博客园ibatis缓存介绍 - 勇泽 - 博客园ibatis缓存介绍 - 勇泽 - 博客园
自己写的ibatis 框架,跟ibatis功能差不多
springsecurity(用spring ibatis freemaker)实现的用户自定义的权限管理页面, 里头包括数据库脚本 和原数据 和原代码 主要参考http://blog.csdn.net/k10509806/article/details/6369131 这个人的文章做的
Java ibatis缓存技术,ibatis缓存的详细解释 值得学习!
• 目前有4种Cache实现,但是无法自定义扩展Cache。 • Cache的数量可以指定。 • Cache的put和get方法内有同步,外部无。所以同一参数同时查询时,Cache是不能命中的。在有一个结果put到Cache后,后续查询才能命中...
spring+ibatis+oracle分页缓存源码
ibatis自定义数据类型在不支持中文的数据库存储汉字
书中既详实地介绍了iBATIS的设计理念和基础知识,也讨论了动态SQL、高速缓存、DAD框架等高级主题,还讲解了iBATIS在实际开发中的应用。书的最后给出了一个设计优雅、层次清晰的示例程序JGameStore,该示例涵盖全书的...
Ibatis调用Oracle存储过程,返回自定义的类型。
ibatis中使用安全的拼接语句,动态查询,大于、小于、等于.doc
ibatis 数据缓存,讨论了ibatis 数据缓存方面的概念,即用法,用到ibatis 数据缓存的可以参考一下
最近遇到需要批量update数据的问题,一开始用了一个for循环去update,数据量大的时候效率很低。...遇到大批数据更新的时候,效率就可想而知了。在google上找了一遍,发现ibatis里有对批量update的支持,挺好的东西。
NULL 博文链接:https://sunfish.iteye.com/blog/1493410
ibatis学习 ibatis总结 ibatis ibatis ibatis