Compass是建立在Lucene基础之上的一款开放源码的JAVA搜索引擎框架。关于Compass的介绍在此我不多讲了,更多了解请直接参考http://www.opensymphony.com/compass。
很多看了Compass的人多少对Compass的配置文件都有点云里雾里的感觉。由于Compass有很多地方都借鉴了Hibernate的思想,在此我结合Hibernate中的思想来帮助我们对Compass的配置文件进行理解。
Hibernate是一个O/R Mapping工具,它可以将实体对象和数据库中的表进行映射。最终通过访问实体对象来达到访问数据库的目的。
Compass是一个搜索引擎框架,它可以将common meta data与实体对象进行映射。最终通过访问common meta data来达到访问对象的目的。
综上所述,Hibernate是对象到数据库。而Compass是common meta data 到对象。
Compass的配置文件主要分成三类:
第一类:*.cmd.xml文件
*.cmd.xml文件是对common meta data进行定义,我们就可以把它是当作Hibernate中的POJO来理解。里面定义了最终搜索的结果中的最基本的元数据。下面是一个*.cmd.xml文件的片断:
< meta - data - group id = " petclinic " displayName = " Petclinic Meta Data " >
< descrīption > Petclinic Meta Data </ descrīption >
< uri > http: // compass/sample/petclinic</uri>
< alias id = " vet " displayName = " Vet " >
< descrīption > Vet alias </ descrīption >
< uri > http: // compass/sample/petclinic/alias/vet</uri>
< name > vet </ name >
</ alias >
…………
< meta - data id = " petType " displayName = " Pet Type " >
< descrīption > The type of a pet </ descrīption >
< uri > http: // compass/sample/petclinic/petType</uri>
< name > petType </ name >
</ meta - data >
</ meta - data - group >
</ compass - core - meta - data >
在这里
可当作是POJO的package来理解,petclinic可以看成是package name。
可当作是POJO的Class来理解,vet 可以看成是class name。
可当作是POJO的property来理解,petType可以看成是property name。
上面xml中所定义的meta data 和alias就是compass需要查询的所有的基本元素组件。
然而common meta data的定义与POJO所不同的是:POJO是用java代码来体现,而common meta data使用xml来体现。POJO的class中定义了property,common meta data中的alias和meta-data是分开定义。
当然上面都是一个类比而已, 其目的是为了便于让我们理解,实际生成的代码并非如上所述的一一对应。compass提供了一个ant task可以将common meta data生成一个class。代码片断如下:
/** */ /**
* Petclinic Meta Data
*/
public static final class Group {
public static final String Id = " petclinic " ;
public static final String DispayName = " Petclinic Meta Data " ;
public static final String Uri = " http://compass/sample/petclinic " ;
}
public static final class Alias {
/** */ /**
* Owner alias
*/
public static final class Owner {
public static final String Id = " owner " ;
public static final String Name = " owner " ;
public static final String DisplayName = " Owner " ;
public static final String Uri = " http://compass/sample/petclinic/alias/owner " ;
public static final String GroupId = " petclinic " ;
}
}
……
}
第二类:*.cpm.xml文件
*.cpm.xml就是Object/Search Engine Mapping了。 我们也可以拿她当作同Hibernate中的*.hbm.xml来理解。他的作用就是提供了POJO到common meta data的映射。下面是一个*.cpm.xml文件的片断:
< contract alias = " entity " >
< id name = " id " />
</ contract >
< contract alias = " person " extends = " entity " >
< property name = " firstName " >
< meta - data > $ {petclinic.firstName} </ meta - data >
</ property >
< property name = " lastName " >
< meta - data > $ {petclinic.lastName} </ meta - data >
</ property >
< property name = " address " >
< meta - data > $ {petclinic.address} </ meta - data >
</ property >
< property name = " city " >
< meta - data > $ {petclinic.city} </ meta - data >
</ property >
< property name = " telephone " >
< meta - data > $ {petclinic.telephone} </ meta - data >
</ property >
</ contract >
< class name = " Specialty " alias = " ${petclinic.specialty} " root = " false " >
< property name = " name " >
< meta - data > $ {petclinic.specialty} </ meta - data >
</ property >
</ class >
< class name = " Owner " alias = " ${petclinic.owner} " extends = " person " >
< property name = " firstName " >
< meta - data > $ {petclinic.firstName} </ meta - data >
</ property >
< property name = " lastName " >
< meta - data > $ {petclinic.lastName} </ meta - data >
</ property >
< property name = " address " >
< meta - data > $ {petclinic.address} </ meta - data >
</ property >
< property name = " city " >
< meta - data > $ {petclinic.city} </ meta - data >
</ property >
< property name = " telephone " >
< meta - data > $ {petclinic.telephone} </ meta - data >
</ property >
< reference name = " petsInternal " ref - alias = " ${petclinic.pet} " />
</ class >
</ compass - core - mapping >
上面 package对应了POJO的包名,class对应了POJO类名,contract为POJO中一些较为Base类, property对应了POJO的属性。上面看到的像ANT中的${*}就是*.cmd.xml 中所定义的common meta data。通常来说*.cmd.xml中的alias同POJO的Class进行映射。Meta data 同Class中的property进行映射。更多的映射的细节在此不多讲。可以参考 Compass的中自带的Sample Petclinic来理解。
第三类:*.cfg.xml文件
Compass的*.cfg.xml文件就和Hibernate的*.cfg.xml有些类似了。下面是一个*.cfg.xml文件的内容:
< compass >
< setting name = " compass.engine.connection " > target / index </ setting >
< meta - data resource = " org/compass/sample/library/library.cmd.xml " />
< mappings >
< class name = " test.Author " />
</ mappings >
</ compass >
</ compass - core - configuration >
上面
指定了索引文件存放的路径。
指定了*.cmd.xml文件存放的路径。
是对compass的mapping文件进行指定。Test.Author对应的文件是test/Author.cpm.xml.
<compass>是对compass中的compass类进行的一些参数设置,这个compass是一个重量级的类,类似于Hibernate中SessionFactory.
当Hibernate同Spring进行整合后,Hibernate就不需要*.cfg.xml这个文件了,借而代之的是用Spring的配置文件来进行配置。同样,Compass同Spring进行整合后,*.cfg.xml也可以不需要了。比如如下的Spring配置。
< property name = " resourceLocations " >
< list >
< value > classpath:org / compass / sample / petclinic / petclinic.cmd.xml </ value >
< value > classpath:petclinic.cpm.xml </ value >
</ list >
</ property >
< property name = " compassSettings " >
< props >
< prop key = " compass.engine.connection " > file: // ${user.home}/compass/petclinic</prop>
< prop key = " compass.transaction.factory " > org.compass.spring.transaction.SpringSyncTransactionFactory </ prop >
</ props >
</ property >
< property name = " transactionManager " >
< ref local = " transactionManager " />
</ property >
</ bean >
< bean id = " hibernateGpsDevice " class = " org.compass.spring.device.hibernate.SpringHibernate3GpsDevice " >
< property name = " name " >< value > hibernateDevice </ value ></ property >
< property name = " sessionFactory " >< ref local = " sessionFactory " /></ property >
</ bean >
< bean id = " compassGps " class = " org.compass.gps.impl.SingleCompassGps " init - method = " start " destroy - method = " stop " >
< property name = " compass " >< ref bean = " compass " /></ property >
< property name = " gpsDevices " >
< list >
< ref local = " hibernateGpsDevice " />
</ list >
</ property >
</ bean >
在上诉的配置文件中又引出了两个新的知识点,CompassGps和CompassGpsDevice。
1 :CompassGps像是一个Service,他需要在application startup时启动服务, application shutdown停止服务,
2 :CompassGpsDevice不能独立的存在,他需要依赖CompassGps,
CompassGps为CompassGpsDevice提供Compass对象,他们一起为程序提供Index的实时更新。 Compass整合Hibernate 等等 persitance framework的代码就在CompassGpsDevice里,你需要提供不同的Device,如HibernateDevice, JDODevice。你也可以实现自己的Device, CompassGpsDevice会把domain object的更新事件通过CompassGps去通知Compass去实时更新索引文件。