1.Compass::Spring
Compass::Spring aim is to provide closer integration with the springframework.
Compass::Spring provides the ability to expose Compass as a Spring bean from an application context file.
Application objects that need to access Compass will obtain a reference to a pre-defined instance via bean
references. The following is an example of a Spring XML application context definition configuring Compass:
<beans>
...
<bean id="compass" class="org.compass.spring.LocalCompassBean">
<property name="resourceLocations">
<list>
<value>classpath:org/compass/spring/test/A.cpm.xml</value>
</list>
</property>
<property name="compassSettings">
<props>
<prop key="compass.engine.connection">
target/testindex
</prop>
<!-- This is the default transaction handling (just explicitly setting it) -->
<prop key="compass.transaction.factory">
org.compass.core.transaction.LocalTransactionFactory
</prop>
</props>
</property>
</bean>
...
</beans>
●Spring AOP
Compass provides a set of Spring AOP Advices which helps to mirror data changes done within a Spring
powered application. For applications with a data source or a tool with no gps device that works with it (or it
does not have mirroring capabilities - like iBatis), the mirror advices can make synchronizing changes made to
the data source and Compass index simpler.
Advices
The AOP support comes with three advices: CompassCreateAdvice, CompassSaveAdvice, and
CompassDeleteAdvice. They can create, save, or delete a data Object respectively. The advices are of type
AfterReturningAdvice, and will persist the change to the index after the method proxied/adviced returns.
The data object that will be used to be created/saved/deleted can be one of the adviced method parameters
(using the parameterIndex property), or it's return value (setting the useReturnValue to true).
Dao Sample
The following is an example using Spring AOP to proxy the dao layer. The Dao layer usually acts as an
abstraction layer on top of the actual data source interaction code. It is one of the most common places where
the Compass advices can be applied . The assumption here is that
the Dao have create/save/delete methods.
<beans>
...
<bean id="compass" class="org.compass.spring.LocalCompassBean">
... // configure a compass instance
</bean>
<!-- define the daos -->
<bean id="userDao" class="eg.UserDaoImpl">
...
</bean>
<bean id="contactDao" class="eg.ContactDaoImpl">
...
</bean>
<!-- Definen the advisors -->
<bean id="compassCreateAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<bean class="org.compass.spring.aop.CompassCreateAdvice">
<property name="compass" ref="compass" />
</bean>
</property>
<property name="pattern" value=".*create" />
</bean>
<bean id="compassSaveAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<bean class="org.compass.spring.aop.CompassSaveAdvice">
<property name="compass" ref="compass" />
</bean>
</property>
<property name="pattern" value=".*save" />
</bean>
<bean id="compassDeleteAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<bean class="org.compass.spring.aop.CompassDeleteAdvice">
<property name="compass" ref="compass" />
</bean>
</property>
<property name="pattern" value=".*delete" />
</bean>
<!-- Auto proxy the daos -->
<bean id="proxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames"><value>userDao, contactDao</value></property>
<property name="interceptorNames">
<list>
<value>compassCreateAdvisor</value>
<value>compassSaveAdvisor</value>
<value>compassDeleteAdvisor</value>
</list>
</property>
</bean>
...
</beans>
2.Compass::Gps
class="org.compass.gps.device.ibatis.SqlMapClientGpsDevice">
<property name="name" value="ibatis" />
<property name="sqlMapClient" ref="sqlMapClient" />
<property name="selectStatementsIds">
<value>getStores</value>
</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> <!-- It holds a list of CompassGpsDevices -->
<bean class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">
<property name="gpsDevice" ref="iBatisGpsDevice" />
</bean>
</list>
</property>
</bean>
<property name="compass">
<ref bean="compass"/>
</property>
</bean
<property name="compassGps" ref=" compassGps"/>
<property name="compassTemplate" ref=" compassTemplate"/>
</bean>
import org.compass.core.CompassDetachedHits;
import org.compass.core.CompassException;
import org.compass.core.CompassHits;
import org.compass.core.CompassQuery;
import org.compass.core.CompassSession;
import org.compass.core.CompassTemplate;
import org.compass.core.CompassTransaction;
import org.compass.gps.CompassGps;
import com.xxxx.search.model.SearchResults;
import com.xxxx.util.SearchCommand;
this.compassTemplate = compassTemplate;
}
this.compassGps = compassGps;
}
this.compassGps.index();
}
SearchResults searchResults;
searchResults = (SearchResults) compassTemplate
.execute(
CompassTransaction.TransactionIsolation.READ_ONLY_READ_COMMITTED,
new CompassCallback() {
public Object doInCompass(CompassSession session)
throws CompassException {
return performSearch(searchCommand, session);
}
});
return searchResults;
}
SearchCommand searchCommand, CompassSession session) {
int iPageSize, page, hitsLength, from, to, pageCount;
long time = System.currentTimeMillis();
CompassQuery query = buildQuery(searchCommand, session);
CompassHits hits = query.hits();
CompassDetachedHits detachedHits;
iPageSize = searchCommand.getPageSize().intValue();
page = 0;
hitsLength = hits.getLength();
if (hitsLength == 0) {
SearchResults searchResults = new SearchResults();
searchResults.setHited(false);
time = System.currentTimeMillis() - time;
searchResults.setSearchTime(time);
return searchResults;
}
if (searchCommand.getPage() != null) {
page = searchCommand.getPage().intValue();
}
from = page * iPageSize;
if (from > hitsLength) {
from = (hitsLength / iPageSize) * iPageSize;
to = hitsLength - 1;
doProcessBeforeDetach(searchCommand, session, hits, from,
hitsLength % iPageSize);
detachedHits = hits.detach(from, hitsLength % iPageSize);
} else if ((from + iPageSize) > hitsLength) {
to = hitsLength - 1;
doProcessBeforeDetach(searchCommand, session, hits, from,
hitsLength % iPageSize);
detachedHits = hits.detach(from, hitsLength % iPageSize);
} else {
to = from + iPageSize - 1;
doProcessBeforeDetach(searchCommand, session, hits, from, iPageSize);
detachedHits = hits.detach(from, iPageSize);
}
doProcessAfterDetach(searchCommand, session, detachedHits);
pageCount = (int) Math.ceil((float) hitsLength / iPageSize);
searchResults.setHited(true);
searchResults.setCurrentPageNumber(page+1);
searchResults.setFrom(from+1);
searchResults.setTo(to+1);
searchResults.setHits(detachedHits.getHits());
searchResults.setHitsLength(hitsLength);
searchResults.setPageCount(pageCount);
searchResults.setPageSize(iPageSize);
time = System.currentTimeMillis() - time;
searchResults.setSearchTime(time);
return searchResults;
}
* Acts as an extension point for search controller that wish to build
* different CompassQueries. <p/> The default implementation uses the
* session to create a query builder and use the queryString option, i.e.:
* <code>session.queryBuilder().queryString(searchCommand.getQuery().trim()).toQuery();</code>.
* <p/> Some other interesting options might be to add sorting to the query,
* adding other queries using a boolean query, or executing a different
* query.
*/
protected CompassQuery buildQuery(SearchCommand searchCommand,
CompassSession session) {
return session.queryBuilder().queryString(
searchCommand.getQuery().trim()).toQuery();
}
* An option to perform any type of processing before the hits are detached.
*/
protected void doProcessBeforeDetach(SearchCommand searchCommand,
CompassSession session, CompassHits hits, int from, int size) {
* An option to perform any type of processing after the hits are detached.
*/
protected void doProcessAfterDetach(SearchCommand searchCommand,
CompassSession session, CompassDetachedHits hits) {
}
上面搜索结果用到了SearchResults类,他包装了搜索结果需要的各种属性及其set(),get()方法