ibatis提供四种缓存方案,LRU、FIFO、MEMORY、EHCACHE,通过定义不同的cacheModel,将数据缓存在cache中。
[size=large][b]具体写法参考如下[/b][/size]
[size=large][b]一、参见com.ibatis.sqlmap.engine.builder.xml.SqlMapParser[/b][/size]
parse在解析xml的时候,遇到一个cacheModel标签,则创建一个CacheModel的对象
并通过如上方法,成功的将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,执行相关的缓存操作
[size=large][b]三、参见com.ibatis.sqlmap.engine.mapping.statement.CachingStatement[/b][/size]
CachingStatement封装了很多query的方法,以executeQueryForObject为例
如果没从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()
[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()