大家都知道用lucene2.2.0全文检索速度很快,但是当并发量的大的时候,lucene也会吃不消的,所以我们可以用到缓存,我给大家介绍的是oscache-2.4.1,先到官方网站下载一个.,然后把oscache-2.4.1.jar导入你的工程中.然后在下载解压后的文件里有个重要的文件,那就是oscache.properties,oscache.tld文件,oscache.properties是对oscache的配置,这两个文件放在classes文件下.,打开oscache.properties文件,里面可以自己进行相关配置.
先介绍用硬盘缓存.
1.打开oscache.properties文件. 改成,cache.memory=false(表示硬盘缓存.true表示内存缓存),然后是路径,cache.path=/home/search/index/cache(我这个不是win下)然后cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.HashDiskPersistenceListener选一个,第一会当缓存数据在硬盘后,会产品一个文件夹.第二是存数据在硬盘后,会产生分步的件夹,不会像第一种那样把缓存数据放在一个文件夹里.
2.写方法进行缓存.
1.写个类extends GeneralCacheAdministrator,
public class BaseCache extends GeneralCacheAdministrator {
// 过期时间(单位为秒);
private int refreshPeriod;
public BaseCache(int refreshPeriod){
super();
this.refreshPeriod=refreshPeriod;
}
// 添加被缓存的对象;
public void put(String key,Object value){
this.putInCache(key,value);
}
// 删除被缓存的对象;
public void remove(String key){
this.flushEntry(key);
}
// 删除所有被缓存的对象;
public void removeAll(Date date){
this.flushAll(date);
}
public void removeAll(){
this.flushAll();
}
// 获取被缓存的对象;
public Object get(String key) throws Exception{
try{
return this.getFromCache(key,this.refreshPeriod);
} catch (NeedsRefreshException e) {
this.cancelUpdate(key);
throw e;
}
}
}
2.执行方法:
在方法里,indexCache = new BaseCache(3600),hii = new cache.Hits(hits),这个类是自己写的,下面的详细代码,然后调用put(String key,Object value)方法,key是关键字.下次取的时候就直接get(key),key我是用的查询参数组成的,只要下次当别人用到相同条件搜索时,就可以直接从缓存读数据,这里所提到的是org.apache.lucene.search.Hits这个对像是不能被缓存的,没有被序例化,我查了下源码,也不能被继承,所以大家自己写个类implements Serializable
public class Hits implements Serializable {
private org.apache.lucene.search.Hits hits;
private Document[] docs=null;
private boolean flag=true;
/**
* sundc 2007-11-20
*/
public Hits(org.apache.lucene.search.Hits hits) {
this.docs=new Document[hits.length()];
int length=0;
//我这里是定义记录有只缓存前710多记录,如果大于710还是查lucene,大家都知道搜索用户访问都是几页,大家可以针对自己项目进行规化..
if(hits.length()>=710){
length=710;
}
else{
length=hits.length();
}
for(int i=0;i<length;i++){
try {
this.docs[i]=hits.doc(i);
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public Hits( Document[] doc){
this.docs=doc;
}
public Document doc(int i){
if(!this.flag){
try {
return this.hits.doc(i);
} catch (CorruptIndexException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return this.docs[i];
}
public int length(){
if(this.flag){
return docs.length;
}
return this.hits.length();
}
public Document[] getDocs() {
return this.docs;
}
public void setDocs(Document[] docs) {
this.docs = docs;
}
public org.apache.lucene.search.Hits getHits() {
return this.hits;
}
public void setHits(org.apache.lucene.search.Hits hits) {
this.hits = hits;
}
}
我这里是如果有缓存数据,就读缓存,没有,就lucene然后放在缓存里.大家可以调用indexCache.get(key),大家每一次访问的时候会相对很慢.如果缓存已经建立了,那么速度会很快,大家在用的时候,针对自己项目的数据要求,进行缓存.下面介绍内存缓存.
2.内存缓存可以相对要快点.但是针对服务器的本身内存大小,大家针对自己的项目和服务器的配置选择好的缓存方式.,把cache.memory=true,这样就可以了.
3.还可以实现页面级缓存
你可以在web.xml中定义缓存过滤器,定义特定资源的缓存。
<filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>time</param-name>
<param-value>60</param-value>
</init-param>
<init-param>
<param-name>scope</param-name>
<param-value>session</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
上面定义将缓存所有.jsp页面,缓存刷新时间为60秒,缓存作用域为Session,
注意,CacheFilter只捕获Http头为200的页面请求,即只对无错误请求作缓存,
而不对其他请求(如500,404,400)作缓存处理.
我这里介绍的不全,只是我在项目中用到了这些.如果有什么问题,虚心接受....