欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

初学cache cacheehcachejavaeql缓存 

程序员文章站 2024-02-28 21:18:52
...
  初次学习cache接触到的Ehcache这个框架。缓存这个概念只让我想起hibernate里面的缓存,不过这都是hibernate自己做的,和自己都没什么关系。为什么要用到缓存,这个貌似应该都知道。
  首先接触Ehcache没有去学习Ehcache的一些基本东西,反而是看整个系统是怎么用它的。
  系统刚跑起来的时候数据不是很多,全部查找出来放入到缓存里面,对每个bean对象都建立了2个缓存。刚开始不知道Ehcache是怎么存的,但是看代码明白有Key,Value二个,key存放id,value存放相应的bean,这就是一个缓存。另一个了,key放条件,value放id。想了好久才明白为什么创建2个,感觉这样挺好的。
  数据放进了Ehcache里面后,该是查数据的时候了。查数据是怎么的顺序了?首先是根据条件查询存放id的那个缓存,如果查询出来的id值不为空,则获得一个listid,然后遍历list,得到id去查询存放bean的缓存。如查到的id为空,则根据条件去存放bean的缓存里去查(查到后,还记得要把条件和id放到缓存里面去)。若根据id去查,和根据条件去查都没有的话,就只能去查数据库了,查完后要把查得到都要放到那二个缓存里面去,这就是查询的逻辑。
  数据放入缓存后,缓存的数据不应该是不变的,因为数据库的数据要更新,那么缓存的数据也应该更新。那怎么做呢?不知道应用的是否观察者模式,但挺像的,对各个bean对象监听起来,监察是否对数据库有改变,那具体监测哪一块了?数据发生变化那么大家肯定会想到事物,数据要提交到数据库里,肯定要调用的transaction,所以在调用commit()方法时,那么就可以通知到相对应bean的缓存了,及时更新。大家初学语言的时候都碰到过这个问题,值传递和引用传递,引用传递在方法里面改变了值,那引用对象的值也变了,涉及到缓存也一样,你从缓存获取出来的对象都是引用类型的,你临时取出来用一下,改变了值,那么缓存也变了,可是数据库没变啊,所以有时结果就出错了,记得取出来的对象一定要重新new一个(把旧对象的值赋值给新的)。

  简单的缓存应用大概是这样的了,我所知道的。 该是要把Ehcache给了解一下了,ehcache若简单应用,其实很容易。主要学会2个地方,ehcache.xml和EQL。
  首先我说下ehcache.xml
 
<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache maxElementsInMemory="10000" eternal="false"
                  overflowToDisk="false" timeToLiveSeconds="180"
                  diskPersistent="false" diskExpiryThreadIntervalSeconds="120" />
    <cache name="PersonBean"
                  memoryStoreEvictionPolicy="LRU"
                  maxElementsInMemory="10000" overflowToDisk="false" eternal="true">
       <searchable>
           <searchAttribute name="N" expression="value.getName()"/>
       </searchable>
    </cache>
</ehcache>
  

diskStore缓存数据文件创建的地方
maxElementsMemory缓存中可以存放的最大元素量,若overflowToDisk为true,超过了则写到磁盘中,一般不会这样做。若为false则按Eviction的策略来替换元素
eternal设置元素是否永恒,则超时策略被忽略,就是timeLive和timeToIdle这二个失效。但仍然遵守替换原则
overflowToDisk设置元素超出最大量时是否保存在磁盘中
timeLiveSeconds设置元素生存时间,到时就被销毁,默认是没有限制
timeToIdleSeconds设置元素空闲时间,意思是一直没有被访问,到达这个时间则销毁,默认没限制
memoryStoreEvictionPolicy设置缓存替换策略,这让我想起了上操作系统这门课时,老师给我们讲的,现在还真的要用上了。
  LRU:least recently used 最近最少使用
  LFU:least frequently used 最不经常使用
  FIFO:first in first out 先入先出
searchAttribute定义查找属性
在工程里我定义了PersonBean这个类,包含了id,name,year,sex属性及其get,set方法。我直接用PersionBean这个名字做为缓存的名字,而这个缓存就是存放PersonBean对象,所以在expression中name的值是value.getName()。

看一下Ehcache的简单代码
CacheManager cacheManager = CacheManager.getInstance();
Ehcache ehcache = cacheManager.getEhcache("PersonBean");
PersonBean perb = new PersonBean();
perb.setId(1);
perb.setName("liuq");
ehcache.put(new Element(1,perb));
Element element = ehcache.get(1);
Object object = element.getObjectValue();

从代码里大家可以看见Ehcache存放的结构。Ehcache管理许多cache,而我们的需要存放的东西是用Element存放在cache中的,以key,value的形式。cache的创建可以写在配置文档里,也可以用编码实现,不过建议是写在文档里,直观。在调用CacheManager.getInstance()时,会自动到src目录下找,名字必须为ehcache.xml.
创建CacheManager还有其它方法,这就看API可以知道。慢慢的越来越发现API是个好东西,以前都是直接看别人写出来,其实还不如自己看API,要养成好习惯。

然后再看一下对cache的查询
Query query = ehcache.createQuery().includeKeys().includeValues();
//Attribute n = ecache.getSearchAttribute("N");
//Criteria c = n.eq("liuq");
//query.addCriteria(c);
query.addCriteria(new Attribute("N").eq("liuq")).end();
//query.addCriteria(Query.KEY.eq(1)).end();  
Results result = query.execute();
for (Result re : result.all()) {
   PersonBean pb = (PersonBean) re.getValue();
   System.out.println(pb.getName());
}     

在Ehcache中查询,也叫EQL。大家可以去官网看一下详细的介绍http://ehcache.org/documentation/apis/search,只是官网是英语的,需要你花时间,但许多东西,看官网的还是觉得好一些。EQL查询步骤其实很简单,创建一个Query,加入查询条件,最后执行得到结果,复杂的是你的查询条件。要做EQL,必须要加入searchable属性,不然会出错的。大家可以看到Attribute是我定义在searchable里面,expression就是类中的getName(),这样才能够得到liuq这个值去匹配。还有其中includeKeys,和includeValues记得加进去,因为re.getKey和re.getValue需要。

  这仅仅是一个简单的了解,至于应用还没怎么学会,需要继续努力学,然后分享更多的知识,若有不对的地方,希望大家能及时指出来。