Ibatis有自己的灵活的,可扩展的Cache支持。其内置的Cache类型有三种:基于内存的,LRU(最近最少使用算法)和FIFO(先进先出)。
一.基本概念
在配置文件中Cache的配置如下:
id 用于唯一标志该cacheModel。
implementation 为ICacheController的具体实现类的全限定名或者框架内部定义的别名--LRU,FIFO,MEMORY。
缓存的flush就是重新使缓存和数据库同步,Ibatis的默认实现是清空缓存。
flushInterval 指定了cache的同步(flush)时间,单位可以指定hours,minutes,seconds等,或不指定(从不flush)。
flushOnExecute 指定在所指定的statement执行后flush缓存。比如对于一个查询语句,当执行插入,更新,删除等操作时缓存就可能存在脏数据,应该被flush。Ibatis会在DomSqlMapBuilder构造CacheModel时,将flushOnExecute中指定的statement通过foreach语句注册Trigger:cacheModel.RegisterTriggerStatement(mappedStatement),而该方法就是通过mappedStatement.Execute +=new ExecuteEventHandler(FlushHandler)为flushOnExecute中指定的statement注册了FlushHandler,也就是在执行后同步(刷新)该CacheModel。
property 指定了具体的ICacheController控制器需要的其他参数属性。
二.基本使用
使用缓存的配置如下:
select * from PRODUCT where PRD_CAT_ID = #value#
缓存是和具体的statement一起使用的,也就是可以为需要缓存的可执行语句指定缓存,也可以不指定。这样增加了缓存的灵活性。
一个比较基本的概念:只有查询的结果需要缓存,所以缓存一定是和select语句一起出现的(说的绝对了点,基本上吧)。而缓存的查询结果在执行了其他与该数据相关的写数据的操作后,就有可能存在脏数据。
现在还没有完全明确的是,如果引起缓存中出现脏数据的mappedSatatement不在当前的配置文件中,是否可以通过全限定名来访问该mappedSatatement(理论上应该可以,需要试验)。
三.原理
对于三种算法:
1.基于内存
基于内存的利用了WeakReference,也就是弱引用。同时,Ibatis自己构造了StrongReference类型,java中还有SOFT类型(.NET中不支持)。内存缓存适用于简单应用和服务器物理内存紧张的环境。它的将对象放入缓存和从缓存中取出对象的算法如下:
public object this[object key]
{
get
{
object value = null;
object reference = _cache[key];
if (reference != null)
{
if (reference is StrongReference)
{
value = ((StrongReference) reference).Target;
}
else if (reference is WeakReference)
{
value = ((WeakReference) reference).Target;
}
}
return value;
}
set
{
object reference = null;
if (_cacheLevel.Equals(MemoryCacheLevel.Weak))
{
reference = new WeakReference(value);
}
else if (_cacheLevel.Equals(MemoryCacheLevel.Strong))
{
reference = new StrongReference(value);
}
_cache[key] = reference;
}
}
也就是,区分了是弱引用还是强引用。cacheLevel默认为WEAK,可以在配置文件中配置。
2.LRU
对于LRU算法,实现如下:
public object this[object key]
{
get
{
_keyList.Remove(key);
_keyList.Add(key);
return _cache[key];
}
set
{
_cache[key] = value;
_keyList.Add(key);
if (_keyList.Count > _cacheSize)
{
object oldestKey = _keyList[0];
_keyList.Remove(0);
_cache.Remove(oldestKey);
}
}
}
也就是,每次取一次缓存都会将该键首先删除然后加入的键list最后,设置缓存对象时,如果缓存大小大于预定大小,将会删除键list的第0个键值。这样就实现了LRU。
3.FIFO
对于FIFO,算法就比较简单了,只是省去了在LRU中获取缓存对象时在存放键(key)的列表中,先删除再添加到list最后的步骤:
_keyList.Remove(key);
_keyList.Add(key);
其他 与LRU一样,所以就是先进先出(永远是最先加入的最先被删除)。
CacheModel
-
关于我们
公司介绍 最新动态 联系我们 -
产品与服务
域名注册 jsp空间 php空间 -
常见问题
空间操作手册 网站备案相关 退款相关问题 -
技术支持
技术 QQ :178966803 联系电话:13616026886 联系邮箱:fjjsp@vip.163.com

扫描关注微信公众号