`
songbin0201
  • 浏览: 319736 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

浅析ibatis的cache实现

 
阅读更多
ibatis提供四种缓存方案,LRU、FIFO、MEMORY、EHCACHE,通过定义不同的cacheModel,将数据缓存在cache中。

具体写法参考如下
<cacheModel id="cache-name" type="LRU" readOnly="true" serialize="false">
    <property name="cache-size" value="1000" />
</cacheModel>

<select id="getBean" resultMap="bean" cacheModel="cache-name">
    <![CDATA[select * from table]]>
</select>


一、参见com.ibatis.sqlmap.engine.builder.xml.SqlMapParser

parser.addNodelet("/sqlMap/cacheModel", new Nodelet() {
      public void process(Node node) throws Exception {
        vars.currentCacheModel = new CacheModel();
        vars.currentProperties = new Properties();
      }
    });

parse在解析xml的时候,遇到一个cacheModel标签,则创建一个CacheModel的对象

vars.currentCacheModel.setControllerClassName(type);

if (vars.client.getDelegate().isCacheModelsEnabled()) {
          vars.client.getDelegate().addCacheModel(vars.currentCacheModel);
}

并通过如上方法,成功的将cacheModel对象加入到map中缓存起来,同时为cacheModel设置缓存控制器(LRU、FIFO、MEMORY、EHCACHE),实现不同的缓存方案

因为是单例模式, SqlMapExecutorDelegate通过HashMap cacheModels ,持有了全部的cacheModel,并作为静态对象全局共享。


二、参见com.ibatis.sqlmap.engine.builder.xml.SqlStatementParser

解析statement时,如果cache可用,获取到对应的cacheModel,执行相关的缓存操作
if (cacheModelName != null && cacheModelName.length() > 0 && vars.client.getDelegate().isCacheModelsEnabled()) {
    CacheModel cacheModel = vars.client.getDelegate().getCacheModel(cacheModelName);
    return new CachingStatement(statement, cacheModel);
}


三、参见com.ibatis.sqlmap.engine.mapping.statement.CachingStatement
CachingStatement封装了很多query的方法,以executeQueryForObject为例
    CacheKey cacheKey = getCacheKey(request, parameterObject);
    cacheKey.update("executeQueryForObject");
    Object object = cacheModel.getObject(cacheKey);
    if (object == CacheModel.NULL_OBJECT){
    	//	This was cached, but null
    	object = null;
    }else if (object == null) {
       object = statement.executeQueryForObject(request, trans, parameterObject, resultObject);
       cacheModel.putObject(cacheKey, object);
    }
    return object;

如果没从cacheModel中获取到缓存数据,则继续查询,并将查询结果放到缓存中。
从这里的代码也能看到,cacheModel是允许存在缓存对象为null的情况,因此如果查询结果为null,也会缓存起来,这里要稍加注意。

四、参加com.ibatis.sqlmap.engine.cache.CacheModel
cacheModel.getObject(cacheKey)的方法,由cacheMode定义的cacheController实现(LRU、FIFO、MEMORY、EHCACHE),cacheModel作为单例类的成员变量,可以全局共享,同样CacheController做为cacheModel的成员变量,也可以全局共享,这样CacheController持有的Map cache和List keyList,也在cacheModel可以控制的范围内全局共享了,这样就实现了缓存的效果。
这里有个有意思的地方,由于cacheModel在getObject的时候,会自动统计request和hit的次数,因此使用缓存的方式,cacheModel可以提供输出缓存命中率的方法 -- 参见 public double getHitRatio()
分享到:
评论
2 楼 ljw8822 2014-08-30  
1 楼 wang_xiao_bao 2012-07-19  
http://www16.atpages.jp/sekom/ibatis-2.3.0.677/doxygen/classcom_1_1ibatis_1_1sqlmap_1_1engine_1_1mapping_1_1statement_1_1_caching_statement.html

相关推荐

Global site tag (gtag.js) - Google Analytics