Ibatis的缓存机制

我们知道Hibernate有自己的缓存机制,Hibernate中分为一级缓存和二级缓存,其中的一级缓存是session缓存,是Hibernate封装好的,不需要我们做任何配置的,一级缓存是与session绑定的,当session生命周期结束的时候对应的一级缓存也就消失了。Hibernate的二级缓存需要自己配置的,很遗憾,一直没去深入了解过,等过了这阶段比较忙的时间一定得好好研究研究Hibernate

至于我们的Ibatis,也是有着自己的缓存机制的,使用ibatis的缓存的时候我们要特别的小心谨慎,保证对缓存对象操作的同步性。

 <!-- 定义缓存 --> 
 <cacheModelid="query_cache_xy" readOnly="false" serialize="true" type="LRU">  
       <flushInterval hours="24" />  
       <flushOnExecute statement="xueyuan.save"  />
       <flushOnExecute statement="xueyuan.edit"  />
       <flushOnExecute statement="xueyuan.del"  />
       <property value="600" name="size" />  
   </cacheModel>

这是一个典型的缓存例子,下面我们参照这个例子看看定义缓存的时候需要制定哪些属性,又包含哪些子元素

id属性  这个不用说,唯一标识

readOnly属性:定义是否是只读缓存

为true的时候表示该缓存为只读缓存 ,这里的只读并不是意味着数据对象一旦放入缓存中就无法再对数据进行修改,而是当数据对象发生变化的时候,如数据对象中的某个属性发生变化,那么数据将从缓存中被废除,下次需要重新从数据库中读取数据,构造新的数据对象。

只读缓存由于他可以被多个用户共享,所以可以提高程序性能,但是有数据更改的时候就会降低效率。还有一方面当用户访问只读缓存的时候,框架会将缓存对象的引用直接返回给用户,当多个线程同时访问的时候,就会出现多个线程同时操作一个对象的问题,会出现线程同步的问题。

当为可读写缓存的时候,当读取到缓存对象的 时候,缓存会返回给你一个原对象的副本,而不是直接将原对象的引用直接返回给你,这样即时是多线程访问该缓存,由于他每个线程获得的都是一个内容相同的对象副本,不会出现线程同步的问题。

同时可读写缓存是可更新的。

serialize  是否为全局缓存,true代表全局缓存

当设置全局缓存的时候,表示多个session访问该缓存的时候会获得相同内容的不同实例对象,也就是前面说的原对象的副本。所以serialize  值为true的前提是readOnly属性必须为true。

下面就该说下type属性了,代表的是应用哪种缓存模型,一共有四种缓存模型供我们选择:

(1)、"MEMORY” (com.ibatis.db.sqlmap.cache.memory.MemoryCacheController)。ibatis直接将数据放进内存中,由GC负责管理,如果属性<property name="reference-type"value="WEAK"/>的值为WEAK、SOFT,GC将根据内存使用情况清理缓存如果该值为Strong,缓存将一直保存,一直到flush。

(2)、“LRU”(com.ibatis.db.sqlmap.cache.lru.LruCacheController)。LRU Cache实现用“近期最少使用”原则来确定如何从 Cache 中清除对象。当 Cache溢出时,最近最少使用的对象将被从 Cache 中清除。使用这种方法,如果一个特定的对象总是被使用,它将保留在 Cache中,而且被清除的可能性最小。对于在较长的期间内,某些用户经常使用某些特定对象的情况(例如,在PaginatedList 和常用的查询关键字结果集中翻页) ,LRU Cache 是一个不错的选择。   

(3)、“FIFO”(com.ibatis.db.sqlmap.cache.fifo.FifoCacheController)。FIFO Cache实现用“先进先出”原则来确定如何从 Cache 中清除对象。当 Cache 溢出时,最先进入Cache 的对象将从 Cache 中清除。对于短时间内持续引用特定的查询而后很可能不再使用的情况,FIFO Cache 是很好的选择。 

(4)、“OSCACHE” (com.ibatis.db.sqlmap.cache.oscache.OSCacheController) 。OSCACHE Cache 实现是OSCache2.0缓存引擎的一个 Plugin。它具有高度的可配置性,分布式,高度的灵活性。

根据不同的要求选择不同的缓存模型,当然我们也可以写自定义缓存,需要实现CacheController接口,type属性的值就是类的名称

再说说他 的子元素:

 <flushIntervalhours="24" />  指的是多长时间刷新,此处指24小时,也可设置分钟、秒等单位

       <flushOnExecute statement="xueyuan.save"  />
       <flushOnExecute statement="xueyuan.edit"  />
       <flushOnExecute statement="xueyuan.del"  />  这个属性指的是当程序调用了这几个statement后缓存会刷新

写个实例验证下缓存,代码如下(测试完全好使):

 

	<!-- 定义缓存 -->	
	<cacheModel id="query_cache_xy" type="LRU" readOnly="false" serialize="true">  
            <flushInterval hours="24" />  
            <flushOnExecute statement="xueyuan.save"  />
            <flushOnExecute statement="xueyuan.edit"  />
            <flushOnExecute statement="xueyuan.del"  />
            <property value="600" name="size" />  
    	</cacheModel> 
	<!-- 查询学院 应用缓存 -->
	<select id="queryXyList"  resultClass="xueyuan" cacheModel="query_cache_xy" >
		select a.xy_id, a.xy_name from xy a
	</select>

例子当中的<property   value="600"  name="size" >指定缓存对象的数量最大为600条

平时用用这个ibatis的缓存也是不错滴。

你可能感兴趣的:(cache,ibatis,LRU,缓存,readOnly)