首先:Compass已死,已经为ElasticSearch取代,你可以把ES看作是Compass 3
Compass整合Spring Hibernate最好通过注解方式,这样就可以省略*.cmd.xml与*.cpm.xml
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"
default-autowire="byName" default-lazy-init="true">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://xxx.xxx.x.xxx:xxxx/xxx?characterEncoding=UTF-8" />
<property name="maxActive" value="30" />
<property name="minIdle" value="5" />
<property name="filters" value="stat" />
<property name="timeBetweenEvictionRunsMillis" value="30" />
<property name="username" value="xxx" />
<property name="password" value="xxx" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
</props>
</property>
</bean>
<!-- Compass ☆☆☆☆-->
<!-- 对全文搜索注解的支持 -->
<bean id="annotationConfiguration" class="org.compass.annotations.config.CompassAnnotationsConfiguration"></bean>
<bean id="compass" class="org.compass.spring.LocalCompassBean" >
<property name="classMappings">
<list>
<value>com.acts.lucene.compass.model.Test</value>
</list>
</property>
<property name="compassConfiguration" ref="annotationConfiguration"/>
<!-- 配置索引相对路径
<property name="connection">
<value>/WebRoot/indexFile</value>
</property>-->
<property name="compassSettings">
<props>
<prop key="compass.engine.connection"> file://d:/index </prop><!-- 设置存放索引的路径 -->
<prop key="compass.transaction.factory">
org.compass.spring.transaction.SpringSyncTransactionFactory
</prop>
<prop key="compass.engine.analyzer.MMAnalyzer.CustomAnalyzer">
net.paoding.analysis.analyzer.PaodingAnalyzer
</prop>
<!-- 配置高亮 -->
<prop key="compass.engine.highlighter.default.formatter.simple.pre">
<![CDATA[<font color="red"><b>]]>
</prop>
<prop key="compass.engine.highlighter.default.formatter.simple.post">
<![CDATA[</b></font>]]>
</prop>
</props>
</property>
<property name="transactionManager" ref="transactionManager"/>
</bean>
<!--
同步更新索引
CompassGps为CompassGpsDevice提供Compass对象,他们一起为程序提供Index的实时更新。
CompassGpsDevice会把domain object的更新事件通过CompassGps去通知Compass去实时更新索引文件。
-->
<bean id="hibernateGpsDevice" class="org.compass.gps.device.hibernate.HibernateGpsDevice">
<property name="name">
<value>hibernateDevice</value>
</property>
<property name="sessionFactory" ref="sessionFactory" />
<!-- 控制当heibernate保存时,index实时同步更新 -->
<property name="mirrorDataChanges" value="true"/>
</bean>
<bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">
<property name="compass" ref="compass" />
<property name="gpsDevices">
<list>
<ref local="hibernateGpsDevice"/>
</list>
</property>
</bean>
<!--
必须有一次创建索引的过程,否则,即使mirrorDataChanges设置为true,也不能实时更新索引;
两种方式创建:定时重建索引(利用quartz)或随Spring ApplicationContext启动而重建索引
-->
<bean id="compassIndexBuilder" class="com.acts.lucene.util.CompassIndexBuilder" lazy-init="false">
<property name="compassGps" ref="compassGps"/>
<!-- 相关属性配置-->
<property name="delay" value="1000" />
<property name="buildIndex" value="false"/>
<property name="period" value="60000" />
</bean>
<!-- 类似hibernateTemplate,简化诸如对Session、Transaction、Exception等操作-->
<bean id="compassTemplate" class="org.compass.core.CompassTemplate">
<property name="compass" ref="compass" />
</bean>
</beans>
Beans
@Searchable
public class Test implements java.io.Serializable {
private static final long serialVersionUID = 1L;
@SearchableId
public String getId() {
return this.id;
}
@SearchableProperty(index=Index.ANALYZED,store=Store.YES)
public String getContent() {
return this.content;
}
@SearchableProperty(index=Index.NOT_ANALYZED,store=Store.YES,boost=2)
public String getCreateName() {
return this.createName;
}
private String id;
private String content;
private String createName;
//...
}
随Spring ApplicationContext启动创建索引类
/**
* implements InitializingBean 随着spring 的初始化而启动
* 默认会在Web应用每次启动时重建索引,可以设置buildIndex属性为false来禁止此功能. 也可以不用本Builder,
* 编写手动调用compassGps.index()的代码.
*/
public class CompassIndexBuilder implements InitializingBean{
private CompassGps compassGps;
private long delay = 1000; // spring启动后 延迟1s 运行程序,进行索引重建
// 是否定时构建索引,默认为定时构建 ,如果置为false 而此程序只在spring初始化时创建索引
boolean buildIndex = false;
private long period = 1000 * 60;// 每隔1min进行一次索引重建,监视数据库中数据的变化
public void afterPropertiesSet() throws Exception {
if (buildIndex) {
buildIndex();
}
}
public void buildIndex() {
Timer timer = new Timer("CompassIndexBuilder", true);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("CompassIndexBuilder开始重建索引 --> Build Compass index at : "+new Date());
long beginTime = System.currentTimeMillis();
// 如果compass实体中定义的索引文件已存在,索引过程中会建立临时索引,
// 索引完成后再进行覆盖.
compassGps.index();
long costTime = System.currentTimeMillis() - beginTime;
System.out.println("CompassIndexBuilder完成重建索引-->用时" + costTime + " milliseconds");
}
}, delay, period);
}
//------------------------------------------------------------------
public void setCompassGps(CompassGps compassGps) {
this.compassGps = compassGps;
}
public void setDelay(long delay) {
this.delay = delay;
}
public void setPeriod(long period) {
this.period = period;
}
public void setBuildIndex(boolean buildIndex) {
this.buildIndex = buildIndex;
}
}
搜索
public JSONArray search(String keyWord,String flag) throws Exception{
JSONArray result=new JSONArray();
CompassSession session = null;
CompassTransaction tx = null;
CompassHits hits = null;
Compass compass = compassTemplate.getCompass();
session = compass.openSession();
tx = session.beginTransaction();
// 按相似度查询
if("1".equals(flag)){
hits = session.find(keyWord);
}else{//按时间查询
CompassQuery query = session.queryBuilder().queryString(keyWord).toQuery();
query.addSort("createTime", SortDirection.REVERSE);
hits = query.hits();
}
//高亮处理,组织数据
CompassHighlighter highlighter = null;
for (int i=0;i<hits.length();i++){
JavaBean bean=(QuesDetailPersonal)hits.data(i);
JSONObject obj=new JSONObject();
highlighter = hits.highlighter(i);
// 内容高亮
if (highlighter.fragment("content") != null) {
obj.put("content",highlighter.fragment("content"));
}else{
obj.put("content", bean.getContent());
}
result.add(obj);
}
hits.close();
tx.commit();
return result;
}