浅析ibatis的cache实现

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

[size=large][b]具体写法参考如下[/b][/size]

<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>


[size=large][b]一、参见com.ibatis.sqlmap.engine.builder.xml.SqlMapParser[/b][/size]

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,并作为静态对象全局共享。


[b][size=large]二、参见com.ibatis.sqlmap.engine.builder.xml.SqlStatementParser[/size][/b]

解析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);
}


[size=large][b]三、参见com.ibatis.sqlmap.engine.mapping.statement.CachingStatement[/b][/size]
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,也会缓存起来,这里要稍加注意。

[b][size=large]四、参加com.ibatis.sqlmap.engine.cache.CacheModel[/size][/b]
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()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值