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" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>
   
 <!-- 定义数据源的Bean ,给Hibernate的sessionFactory-->
 <bean id="dataSource"
  class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" 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"
  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="dataSource"><ref bean="dataSource" /></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" class="com.lice.dao.hibernate.ProductDaoHibernate">
  <property name="sessionFactory" ref="sessionFactory"></property>
 </bean>
 
 <bean name="productManager" class="com.lice.service.impl.ProductManagerImpl ">
  <property name="productDao" ref="productDao"></property>
  <property name="compassTemplate" ref="compassTemplate"></property>
 </bean>
 
 <bean id="compassManager" class="com.lice.service.impl.CompassManagerImpl">
  <property name="compassTemplate" ref="compassTemplate"></property>
 </bean>
 
 <bean id="productBean" class="com.lice.action.ProductAction" scope="prototype">
  <property name="productManager" ref="productManager"></property>
  <property name="compassManager" ref="compassManager"></property>
 </bean>
 
 <!-- 配置事务管理器 --> 
 <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory">
   <ref local="sessionFactory"/>
  </property>
 </bean>
   
    <!-- 配置事务特性,配置add、delete和update开始的方法,事务传播特性为required-->      
    <tx:advice id="txAdvice" 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"
  class="org.compass.gps.device.jdbc.mapping.ResultSetToResourceMapping">
  <property name="alias"> <value>product</value></property>
  <property name="indexUnMappedColumns"><value>false</value></property>
  <property name="selectQuery">
   <value>
    select t.product_id as productId ,t.version as version,t.product_name as productName
    ,t.product_price as productPrice ,t.product_brand as productBrand
    ,t.product_desc as productDesc from product t
        </value>
  </property>
  <property name="versionQuery">
   <value>
    select t.product_id as productId ,COALESCE(t.version, 0) as version from product t
   </value>
  </property>
  <property name="idMappings">
   <list>
    <bean class="org.compass.gps.device.jdbc.mapping.IdColumnToPropertyMapping">
     <property name="columnName"><value>productId</value></property>
     <property name="propertyName"><value>productId</value></property>
     <property name="columnNameForVersion"><value>t.product_id</value></property>
    </bean>
   </list>
  </property>
  <property name="dataMappings">
   <list>
    <bean class="org.compass.gps.device.jdbc.mapping.DataColumnToPropertyMapping">
     <property name="columnName"><value>productName</value></property>
     <property name="propertyName"><value>productName</value></property>
    </bean>
    <bean class="org.compass.gps.device.jdbc.mapping.DataColumnToPropertyMapping">
     <property name="columnName"><value>productPrice</value></property>
     <property name="propertyName"><value>productPrice</value></property>
    </bean>
    <bean class="org.compass.gps.device.jdbc.mapping.DataColumnToPropertyMapping">
     <property name="columnName"><value>productBrand</value></property>
     <property name="propertyName"><value>productBrand</value></property>
    </bean>
    <bean class="org.compass.gps.device.jdbc.mapping.DataColumnToPropertyMapping">
     <property name="columnName"><value>productDesc</value></property>
     <property name="propertyName"><value>productDesc</value></property>
    </bean>
   </list>
  </property>
  
  <property name="versionMappings">
         <list>
           <bean class="org.compass.gps.device.jdbc.mapping.VersionColumnMapping">
             <property name="columnName"><value>version</value></property>
           </bean>
         </list>
       </property>
  
 </bean>

 <bean id="productMappingResolver"
  class="org.compass.gps.device.jdbc.ResultSetResourceMappingResolver">
  <property name="mapping"><ref local="productMapping" /></property>
  <property name="dataSource"><ref bean="dataSource" /></property>
 </bean>

 <bean id="compass" class="org.compass.spring.LocalCompassBean">
  <property name="mappingResolvers">
   <list>
    <ref local="productMappingResolver" />
   </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" class="org.compass.gps.device.jdbc.ResultSetJdbcGpsDevice">
  <property name="name"><value>jdbcDevice</value></property>
  <property name="dataSource"><ref bean="dataSource" /></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 class="org.compass.gps.device.jdbc.snapshot.FSJdbcSnapshotPersister">
    <property name="path" value="target/compass/snapshot" />
   </bean>
  </property>
 </bean>

 <bean id="scheduledJdbcGpsDevice" class="org.compass.gps.device.ScheduledMirrorGpsDevice">
  <property name="gpsDevice" ref="jdbcGpsDevice" />
  <property name="mirrorDataChanges" value="true"></property>
  <property name="period">
   <value>1800000</value>
  </property>
 </bean>

 <bean id="hibernateGpsDevice" class="org.compass.gps.device.hibernate.HibernateGpsDevice">
  <property name="name"><value>hibernateDevice</value></property>
  <property name="sessionFactory" ref="sessionFactory" />
  <!-- 操作数据库更新索引 -->
  <property name="mirrorDataChanges"><value>true</value></property>
 </bean>

 <!-- 同步更新索引 -->
 <bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps">
  <property name="compass" ref="compass" />
  <property name="gpsDevices">
   <list>
    <ref bean="scheduledJdbcGpsDevice"/>
   </list>
  </property>
 </bean>
 <bean id="compassTemplate" class="org.compass.core.CompassTemplate">
  <property name="compass" 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"
  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <property name="triggers">
   <list>
    <ref local="compassTrigger" />
   </list>
  </property>
 </bean>

 <!-- 触发器-->
 <bean id="compassTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
  <!-- 装配将要被调度的工作 -->
  <property name="jobDetail" ref="compassJob" />
  <!-- 延迟工作的第一次执行时间 eg.120秒后 -->
  <property name="startDelay" value="120000" />
  <!-- 触发器运行这个工作的频度(以毫秒作为单位 -->
  <property name="repeatInterval" value="300000" />
 </bean>
 
 <!-- 定时触发 -->
 <bean id="cronCompassTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
  <property name="jobDetail" 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();
     }
    }

}

你可能感兴趣的:(bean,Hibernate,quartz,jdbc,ssh)