Compass整合SSH
经过三天的折腾,终于把Compass整合SSH搞定了,下边贴出源码,给正在学习的朋友,毕竟网上关于Compass的详细介绍还是太少了。
我用到的版本是struts2+spring 2.5 +hibernate 3.2+compass 2.2+Quartz 1.6
一、创建一张表,表名PRODUCT
CREATE TABLE "LICE"."PRODUCT"
?? (?"PRODUCT_ID" VARCHAR2(40) NOT NULL ENABLE,
?"PRODUCT_NAME" VARCHAR2(80),
?"PRODUCT_PRICE" NUMBER(6,2),
?"PRODUCT_BRAND" VARCHAR2(40),
?"PRODUCT_DESC" VARCHAR2(200),
?"VERSION" NUMBER(10,0),
? PRIMARY KEY ("PRODUCT_ID")
??? )
二、PRODUCT表对应的实体类
package com.lice.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;
import org.hibernate.annotations.GenericGenerator;
import org.compass.annotations.*;
@Entity
@Table(name = "PRODUCT", schema = "LICE")
@Searchable
public class Product implements java.io.Serializable {
?
?// Fields
?@SearchableId
?private String productId;
?@SearchableProperty(name="productName")
?private String productName;
?@SearchableProperty(name="productPrice")
?private Double productPrice;
?@SearchableProperty(name="productBrand")
?private String productBrand;
?@SearchableProperty(name="productDesc")
?private String productDesc;
?@SearchableProperty(name="version")
?private Integer version;
?// Constructors
?
?public Product() {
?}
?
?public Product(String productName, Double productPrice,
???String productBrand, String productDesc) {
??this.productName = productName;
??this.productPrice = productPrice;
??this.productBrand = productBrand;
??this.productDesc = productDesc;
?}
?// Property accessors
?@GenericGenerator(name = "generator", strategy = "uuid.hex")
?@Id
?@GeneratedValue(generator = "generator")
?@Column(name = "PRODUCT_ID", unique = true, nullable = false, length = 40)
?public String getProductId() {
??return this.productId;
?}
?public void setProductId(String productId) {
??this.productId = productId;
?}
?@Column(name = "PRODUCT_NAME", length = 80)
?public String getProductName() {
??return this.productName;
?}
?public void setProductName(String productName) {
??this.productName = productName;
?}
?@Column(name = "PRODUCT_PRICE", precision = 6)
?public Double getProductPrice() {
??return this.productPrice;
?}
?public void setProductPrice(Double productPrice) {
??this.productPrice = productPrice;
?}
?@Column(name = "PRODUCT_BRAND", length = 40)
?public String getProductBrand() {
??return this.productBrand;
?}
?public void setProductBrand(String productBrand) {
??this.productBrand = productBrand;
?}
?@Column(name = "PRODUCT_DESC", length = 200)
?public String getProductDesc() {
??return this.productDesc;
?}
?public void setProductDesc(String productDesc) {
??this.productDesc = productDesc;
?}
?@Version
?public Integer getVersion() {
??return version;
?}
?public void setVersion(Integer version) {
??this.version = version;
?}
}
注意如果要用hibernate查询,model里必须加上@SearchableProperty(name="XXXX")这种注释。
三、对象的DAO和实现类
import java.util.List;
import com.lice.model.Product;
public interface ProductDao {
?public void create(Product p);
?public Product getProduct(String id);
?public List getProducts();
?public void update(Product product);
?public void remove(String id);
}
package com.lice.dao.hibernate;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.lice.dao.ProductDao;
import com.lice.model.Product;
public class ProductDaoHibernate extends HibernateDaoSupport implements ProductDao {
?public void create(Product p) {
??getHibernateTemplate().save(p);
?}
?public Product getProduct(String id) {
??return (Product)getHibernateTemplate().get(Product.class, id);
?}
?public List getProducts() {
??return getHibernateTemplate().find("from Product order by id desc");
?}
?public void remove(String id) {
??getHibernateTemplate().delete(getProduct(id));
?}
?public void update(Product product) {
??getHibernateTemplate().saveOrUpdate(product);
?}
}
四、对应的Service和实现类
import java.util.List;
import com.lice.model.Product;
public interface ProductManager {
?public void insertProduct(Product p);
?public Product findProdcut(String id);
}
package com.lice.service.impl;
import java.util.ArrayList;
import java.util.List;
import com.lice.dao.ProductDao;
import com.lice.model.Product;
import com.lice.service.ProductManager;
public class ProductManagerImpl implements ProductManager {
?
?private ProductDao productDao;
?
?public Product findProdcut(String id) {
??return productDao.getProduct(id);
?}
?public void insertProduct(Product p) {
??productDao.create(p);
?}
?public ProductDao getProductDao() {
??return productDao;
?}
?public void setProductDao(ProductDao productDao) {
??this.productDao = productDao;
?}
}
五、对应的action
package com.lice.action;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import com.lice.model.Product;
import com.lice.service.CompassManager;
import com.lice.service.ProductManager;
import com.opensymphony.xwork2.ActionSupport;
public class ProductAction extends ActionSupport{
?
?private static final long serialVersionUID = -2189044281576376151L;
?
?private ProductManager productManager;
?
?private CompassManager compassManager;
?
?private Product product;
?
?private String queryString;
?
?
?public String insert(){
??productManager.insertProduct(product);
??return SUCCESS;
?}
?public String search(){
??List results=compassManager.productCompass(queryString);
??System.out.println(results.size());
??ServletActionContext.getRequest().setAttribute("searchresults", results);
??return SUCCESS;
?}
?public ProductManager getProductManager() {
??return productManager;
?}
?public void setProductManager(ProductManager productManager) {
??this.productManager = productManager;
?}
?
?public Product getProduct() {
??return product;
?}
?public void setProduct(Product product) {
??this.product = product;
?}
?public String getQueryString() {
??return queryString;
?}
?public void setQueryString(String queryString) {
??this.queryString = queryString;
?}
?public CompassManager getCompassManager() {
??return compassManager;
?}
?public void setCompassManager(CompassManager compassManager) {
??this.compassManager = compassManager;
?}
}
六、配置文件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: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-2.5.xsd
?????? http://www.springframework.org/schema/tx
?????? http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
?????? http://www.springframework.org/schema/aop
?????? http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" default-lazy-init="true">
??????
?<!-- load jdbc.properties -->
??? <bean id="propertyConfigurer" value="${jdbc.driverClassName}"/>
??<property name="url" value="${jdbc.url}" />
??<property name="username" value="${jdbc.username}"></property>
??<property name="password" value="${jdbc.password}"></property>
??<property name="maxActive" value="${jdbc.maxActive}"/>
??????? <property name="maxWait" value="${jdbc.maxWait}"/>
??????? <property name="poolPreparedStatements" value="${jdbc.poolPreparedStatements}"/>
??????? <property name="defaultAutoCommit" value="${jdbc.defaultAutoCommit}"/>
??????? <property name="logAbandoned" value="${jdbc.logAbandoned}"/>
??????? <property name="removeAbandoned" value="${jdbc.removeAbandoned}"/>???
???<property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}"/>
?</bean>
?
?<!-- 定义Hibernate的sessionFactory,通过该Bean,可以获得Hibernate的Session-->
?<!-- 如果hibernate用了annotation,这里必须用AnnotationSessionFactoryBean -->
?<bean id="sessionFactory"
??/></property>
??<property name="hibernateProperties">
???<props>
????<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
????<prop key="hibernate.show_sql">true</prop>
????<prop key="hibernate.cache.use_second_level_cache">true</prop>
????<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
????<prop key="hibernate.jdbc.fetch_size">30</prop>
????<prop key="hibernate.jdbc.batch_size">50</prop>
????<prop key="hibernate.statement_cache.size">0</prop>
???</props>
??</property>
??<property name="configLocation" value="classpath:hibernate.cfg.xml" />
?</bean>
?
?<bean name="productDao" ref="sessionFactory"></property>
?</bean>
?
?<bean name="productManager" ref="productDao"></property>
??<property name="compassTemplate" ref="compassTemplate"></property>
?</bean>
?
?<bean id="compassManager" ref="compassTemplate"></property>
?</bean>
?
?<bean id="productBean" scope="prototype">
??<property name="productManager" ref="productManager"></property>
??<property name="compassManager" ref="compassManager"></property>
?</bean>
?
?<!-- 配置事务管理器 -->?
?<bean id="transactionManager" transaction-manager="transactionManager">
??? ?<tx:attributes>
??? ??<tx:method name="insert*" propagation="REQUIRED"/>
??? ??<tx:method name="delete*" propagation="REQUIRED"/>
??? ??<tx:method name="update*" propagation="REQUIRED"/>
??? ??<tx:method name="*" read-only="true"/>
??? ?</tx:attributes>
??? </tx:advice>
???
??? <!-- 配置那些类的方法进行事务管理,当前com.lice.service包中的子包、类中所有方法需要,还需要参考tx:advice的设置 -->
??? <aop:config>
??? ?<aop:pointcut id="allManagerMethod" expression="execution (* com.lice.service.*.*(..))"/>
??? ?<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
??? </aop:config>??
</beans>
七、配置文件applicationContext-compass.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"
?xsi:schemaLocation=" http://www.springframework.org/schema/beans? http://www.springframework.org/schema/beans/spring-
beans-2.5.xsd"
?default-lazy-init="true">
?<!-- productMapping Mapping -->
?<bean id="productMapping"
??/></property>
??<property name="dataSource"><ref bean="dataSource" /></property>
?</bean>
?<bean id="compass" />
???</list>
??</property>
??<property name="compassSettings">
???<props>
????<prop key="compass.engine.connection">target/compass</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.analyzer.MMAnalyzer.CustomAnalyzer">
?????org.apache.lucene.annalysis.cn.SmartChineseAnalyzer
????</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>
?<bean id="jdbcGpsDevice" /></property>
??<!-- 同步更新索引 -->
??<property name="mirrorDataChanges"><value>false</value></property>
??<property name="saveSnapshotAfterMirror"><value>false</value></property>
??<property name="mappings">
???<list>
????<ref local="productMapping" />
???</list>
??</property>
??<property name="snapshotPersister">
???<bean value="target/compass/snapshot" />
???</bean>
??</property>
?</bean>
?<bean id="scheduledJdbcGpsDevice" ref="jdbcGpsDevice" />
??<property name="mirrorDataChanges" value="true"></property>
??<property name="period">
???<value>1800000</value>
??</property>
?</bean>
?<bean id="hibernateGpsDevice" ref="sessionFactory" />
??<!-- 操作数据库更新索引 -->
??<property name="mirrorDataChanges"><value>true</value></property>
?</bean>
?<!-- 同步更新索引 -->
?<bean id="compassGps" ref="compass" />
??<property name="gpsDevices">
???<list>
????<ref bean="scheduledJdbcGpsDevice"/>
???</list>
??</property>
?</bean>
?<bean id="compassTemplate" ref="compass" />
?</bean>
</beans>
八、定时触发的Java文件和配置文件applicationContext-jobs.xml
package com.lice.task;
import org.apache.log4j.Logger;
import org.compass.gps.CompassGps;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class CompassTask extends QuartzJobBean{
?private Logger log = Logger.getLogger(CompassTask.class);
?
?private CompassGps compassGps;
?protected void executeInternal(JobExecutionContext context)
???throws JobExecutionException {
??long beginTime = System.currentTimeMillis();
??log.info("--------compass job----------");
??if (compassGps == null)
???return;
??log.info("-------- compass job start ---------");
??compassGps.index();
??log.info("-------- compass job end -------- :" + (System.currentTimeMillis() - beginTime));
?}
?public CompassGps getCompassGps() {
??return compassGps;
?}
?public void setCompassGps(CompassGps compassGps) {
??this.compassGps = compassGps;
?}?
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
??? "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
?<!-- Quartz Scheduler, with pre-registered triggers -->
?<!-- Will automatically start scheduling on context startup -->
?<bean id="scheduler"
??/>
???</list>
??</property>
?</bean>
?<!-- 触发器-->
?<bean id="compassTrigger" ref="compassJob" />
??<!-- 延迟工作的第一次执行时间 eg.120秒后 -->
??<property name="startDelay" value="120000" />
??<!-- 触发器运行这个工作的频度(以毫秒作为单位 -->
??<property name="repeatInterval" value="300000" />
?</bean>
?
?<!-- 定时触发 -->
?<bean id="cronCompassTrigger" ref="compassJob" />
??? ?<property name="cronExpression">
????? ??<value>0 0 6 * * ?</value>
??? ?</property>
?</bean>
?
?<bean name="compassJob" class="org.springframework.scheduling.quartz.JobDetailBean">
??<property name="jobClass">
???<value>com.lice.task.CompassTask</value>
??</property>
??<!-- 给 CompassTask要注入的参数-->
??<property name="jobDataAsMap">
???<map>
????<entry key="compassGps">
?????<ref bean="compassGps"/>
????</entry>
???</map>
??</property>
?</bean>
</beans>
九、配置一个中文分词paoding-dic-home.properties
paoding.dic.home=C:/paoding/dic
paoding.dic.detector.interval=60
十、hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
??? "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
??? <session-factory>
??????? <mapping class="com.lice.model.Product"/>
??? </session-factory>
</hibernate-configuration>
十一、启动加载的一个lintener
package com.lice.listener;
import java.io.File;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.compass.gps.CompassGps;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class StartupListener implements ServletContextListener {
?private static final Log log = LogFactory.getLog(StartupListener.class);
?
?public static ApplicationContext ctx = null;
?
?public void contextDestroyed(ServletContextEvent arg0) {
??// TODO Auto-generated method stub
?}
?public void contextInitialized(ServletContextEvent event) {
??ServletContext context = event.getServletContext();
??
??try{
???ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
???CompassGps compassGps=(CompassGps) ctx.getBean("compassGps");
???
???if(!compassGps.isRunning()){
????compassGps.start();
????log.info("删除现有索引");
????File f=new File("lucene/indexes");
????if(f.exists()){
?????deleteFiles(f);
????}
????log.info("原始索引文件删除完毕");
????log.info("compass开始构建索引");
????new Thread(){
?????public void run(){
??????try{
???????((CompassGps)ctx.getBean("compassGps")).index();
???????log.info("compass成功构建索引");
??????}catch(Exception e){
???????e.printStackTrace();
???????log.error("compass构建索引失败",e);
??????}
?????}
????}.start();
???}
??}catch(Exception e){
???log.error("加载compass错误",e);
??}
?}
?
?private void deleteFiles(File tmpFile){
??? ?if(tmpFile.isDirectory()){
??? ??for(File file:tmpFile.listFiles()){
??? ???deleteFiles(file);
??? ??}
??? ?}else{
??? ??tmpFile.delete();
??? ?}
??? }
}