spring + compass+JPA整合

1.去官方網站下載compass的jar包,我用的的2.1版本
http://www.compass-project.org/

ProductInfo.java

Java代碼

@Entity  

@Searchable  

public class ProductInfo implements Serializable{   

    private Integer id;   

    /** 貨號 **/  

    private String code;   

    /** 產品名稱 **/  

    private String name;   

    /** 產品類型 **/  

    private ProductType type;   

    /** 產品樣式 **/  

    private Set<ProductStyle> styles = new HashSet<ProductStyle>();   

  

    public ProductInfo() {}   

       

    @OneToMany(cascade={CascadeType.REMOVE,CascadeType.PERSIST}, mappedBy="product",fetch=FetchType.EAGER)   

    @OrderBy("visible desc, id asc")   

    @SearchableReference  

    public Set<ProductStyle> getStyles() {   

        return styles;   

    }   

    public void setStyles(Set<ProductStyle> styles) {   

        this.styles = styles;   

    }   

  

       

    @Id @GeneratedValue  

    @SearchableId  

    public Integer getId() {   

        return id;   

    }   

    public void setId(Integer id) {   

        this.id = id;   

    }   

    @Column(length=30)   

    @SearchableProperty(index = Index.TOKENIZED, store = Store.YES)   

    public String getCode() {   

        return code;   

    }   

    public void setCode(String code) {   

        this.code = code;   

    }   

    @Column(length=50,nullable=false)   

    @SearchableProperty(index = Index.TOKENIZED, store = Store.YES)   

    public String getName() {   

        return name;   

    }   

    public void setName(String name) {   

        this.name = name;   

    }   

  

    @ManyToOne(cascade=CascadeType.REFRESH,optional=false)   

    @JoinColumn(name="typeid")   

    @SearchableReference  

    public ProductType getType() {   

        return type;   

    }   

    public void setType(ProductType type) {   

        this.type = type;   

    }   

  

       

    @Override  

    public int hashCode() {   

        final int prime = 31;   

        int result = 1;   

        result = prime * result + ((id == null) ? 0 : id.hashCode());   

        return result;   

    }   

    @Override  

    public boolean equals(Object obj) {   

        if (this == obj)   

            return true;   

        if (obj == null)   

            return false;   

        if (getClass() != obj.getClass())   

            return false;   

        final ProductInfo other = (ProductInfo) obj;   

        if (id == null) {   

            if (other.id != null)   

                return false;   

        } else if (!id.equals(other.id))   

            return false;   

        return true;   

    }   

}  

@Entity
@Searchable
public class ProductInfo implements Serializable{
	private static final long serialVersionUID = -8860864584425256200L;
	private Integer id;
	/** 貨號 **/
	private String code;
	/** 產品名稱 **/
	private String name;
	/** 產品類型 **/
	private ProductType type;
	/** 產品樣式 **/
	private Set<ProductStyle> styles = new HashSet<ProductStyle>();

	public ProductInfo() {}
	
	@OneToMany(cascade={CascadeType.REMOVE,CascadeType.PERSIST}, mappedBy="product",fetch=FetchType.EAGER)
	@OrderBy("visible desc, id asc")
	@SearchableReference
	public Set<ProductStyle> getStyles() {
		return styles;
	}
	public void setStyles(Set<ProductStyle> styles) {
		this.styles = styles;
	}

	
	@Id @GeneratedValue
	@SearchableId
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	@Column(length=30)
	@SearchableProperty(index = Index.TOKENIZED, store = Store.YES)
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	@Column(length=50,nullable=false)
	@SearchableProperty(index = Index.TOKENIZED, store = Store.YES)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@ManyToOne(cascade=CascadeType.REFRESH,optional=false)
	@JoinColumn(name="typeid")
	@SearchableReference
	public ProductType getType() {
		return type;
	}
	public void setType(ProductType type) {
		this.type = type;
	}

	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final ProductInfo other = (ProductInfo) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
}




ProductType.java

Java代碼

  

@Entity  

@Searchable  

public class ProductType implements Serializable{   

    private static final long serialVersionUID = 8106351120886053881L;   

    /** 類別id **/  

    private Integer typeid;   

    /** 類別名稱 **/  

    private String name;   

    /** 子類別 **/  

    private Set<ProductType> childtypes = new HashSet<ProductType>();   

    /** 所屬父類 **/  

    private ProductType parent;   

       

    private Set<ProductInfo> products = new HashSet<ProductInfo>();   

       

    @OneToMany(mappedBy="type", cascade=CascadeType.REMOVE)   

    @SearchableReference  

    public Set<ProductInfo> getProducts() {   

        return products;   

    }   

  

    public void setProducts(Set<ProductInfo> products) {   

        this.products = products;   

    }   

  

    public ProductType() {}   

       

  

    @ManyToOne(cascade=CascadeType.REFRESH)   

    @JoinColumn(name="parentid")   

    public ProductType getParent() {   

        return parent;   

    }   

  

    public void setParent(ProductType parent) {   

        this.parent = parent;   

    }   

    @OneToMany(cascade={CascadeType.REFRESH,CascadeType.REMOVE},mappedBy="parent")   

    public Set<ProductType> getChildtypes() {   

        return childtypes;   

    }   

  

    public void setChildtypes(Set<ProductType> childtypes) {   

        this.childtypes = childtypes;   

    }   

  

    @Column(length=36,nullable=false)   

    public String getName() {   

        return name;   

    }   

  

    public void setName(String name) {   

        this.name = name;   

    }   

  

    @Id @GeneratedValue(strategy=GenerationType.AUTO)   

    @SearchableId  

    public Integer getTypeid() {   

        return typeid;   

    }   

  

    public void setTypeid(Integer typeid) {   

        this.typeid = typeid;   

    }   

  

    @Override  

    public int hashCode() {   

        final int prime = 31;   

        int result = 1;   

        result = prime * result + ((typeid == null) ? 0 : typeid.hashCode());   

        return result;   

    }   

  

    @Override  

    public boolean equals(Object obj) {   

        if (this == obj)   

            return true;   

        if (obj == null)   

            return false;   

        if (getClass() != obj.getClass())   

            return false;   

        final ProductType other = (ProductType) obj;   

        if (typeid == null) {   

            if (other.typeid != null)   

                return false;   

        } else if (!typeid.equals(other.typeid))   

            return false;   

        return true;   

    }   

}  

@Entity
@Searchable
public class ProductType implements Serializable{
	private static final long serialVersionUID = 8106351120886053881L;
	/** 類別id **/
	private Integer typeid;
	/** 類別名稱 **/
	private String name;
	/** 子類別 **/
	private Set<ProductType> childtypes = new HashSet<ProductType>();
	/** 所屬父類 **/
	private ProductType parent;
	
	private Set<ProductInfo> products = new HashSet<ProductInfo>();
	
	@OneToMany(mappedBy="type", cascade=CascadeType.REMOVE)
	@SearchableReference
	public Set<ProductInfo> getProducts() {
		return products;
	}

	public void setProducts(Set<ProductInfo> products) {
		this.products = products;
	}

	public ProductType() {}
	

	@ManyToOne(cascade=CascadeType.REFRESH)
	@JoinColumn(name="parentid")
	public ProductType getParent() {
		return parent;
	}

	public void setParent(ProductType parent) {
		this.parent = parent;
	}
	@OneToMany(cascade={CascadeType.REFRESH,CascadeType.REMOVE},mappedBy="parent")
	public Set<ProductType> getChildtypes() {
		return childtypes;
	}

	public void setChildtypes(Set<ProductType> childtypes) {
		this.childtypes = childtypes;
	}

	@Column(length=36,nullable=false)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Id @GeneratedValue(strategy=GenerationType.AUTO)
	@SearchableId
	public Integer getTypeid() {
		return typeid;
	}

	public void setTypeid(Integer typeid) {
		this.typeid = typeid;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((typeid == null) ? 0 : typeid.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final ProductType other = (ProductType) obj;
		if (typeid == null) {
			if (other.typeid != null)
				return false;
		} else if (!typeid.equals(other.typeid))
			return false;
		return true;
	}
}



ProductStyle.java

Java代碼

  

@Entity  

@Searchable  

public class ProductStyle implements Serializable{   

    private static final long serialVersionUID = -4926119953511144279L;   

    private Integer id;   

    /** 樣式的名稱 **/  

    private String name;   

    /** 圖片 **/  

    private String imagename;   

    private String image140FullPath;   

    /** 是否可見 **/  

    private Boolean visible = true;   

    private ProductInfo product;   

       

    public ProductStyle() {}   

       

    public ProductStyle(Integer id) {   

        this.id = id;   

    }   

  

    public ProductStyle(String name, String imagename) {   

        this.name = name;   

        this.imagename = imagename;   

    }   

    @ManyToOne(cascade=CascadeType.REFRESH,optional=false)   

    @JoinColumn(name="productid")   

    @SearchableReference  

    public ProductInfo getProduct() {   

        return product;   

    }   

    public void setProduct(ProductInfo product) {   

        this.product = product;   

    }   

    @Id @GeneratedValue  

    @SearchableId  

    public Integer getId() {   

        return id;   

    }   

    public void setId(Integer id) {   

        this.id = id;   

    }   

    @Column(length=30,nullable=false)   

    public String getName() {   

        return name;   

    }   

    public void setName(String name) {   

        this.name = name;   

    }   

    @Column(length=40,nullable=false)   

    @SearchableProperty(index = Index.UN_TOKENIZED, store = Store.YES)   

    public String getImagename() {   

        return imagename;   

    }   

    public void setImagename(String imagename) {   

        this.imagename = imagename;   

    }   

    @Column(nullable=false)   

    public Boolean getVisible() {   

        return visible;   

    }   

    public void setVisible(Boolean visible) {   

        this.visible = visible;   

    }   

    @Transient  

    public String getImageFullPath(){   

        return "/images/product/"this.getProduct().getType().getTypeid()+ "/"+   

        this.getProduct().getId()+ "/prototype/"this.imagename;   

    }   

       

    @Transient  

    public String getImage140FullPath(){   

        image140FullPath = "/images/product/"this.getProduct().getType().getTypeid()+ "/"+   

        this.getProduct().getId()+ "/140x/"this.imagename;   

        return image140FullPath;   

    }   

       

    @Override  

    public int hashCode() {   

        final int prime = 31;   

        int result = 1;   

        result = prime * result + ((id == null) ? 0 : id.hashCode());   

        return result;   

    }   

    @Override  

    public boolean equals(Object obj) {   

        if (this == obj)   

            return true;   

        if (obj == null)   

            return false;   

        if (getClass() != obj.getClass())   

            return false;   

        final ProductStyle other = (ProductStyle) obj;   

        if (id == null) {   

            if (other.id != null)   

                return false;   

        } else if (!id.equals(other.id))   

            return false;   

        return true;   

    }   

}  

@Entity
@Searchable
public class ProductStyle implements Serializable{
	private static final long serialVersionUID = -4926119953511144279L;
	private Integer id;
	/** 樣式的名稱 **/
	private String name;
	/** 圖片 **/
	private String imagename;
	private String image140FullPath;
	/** 是否可見 **/
	private Boolean visible = true;
	private ProductInfo product;
	
	public ProductStyle() {}
	
	public ProductStyle(Integer id) {
		this.id = id;
	}

	public ProductStyle(String name, String imagename) {
		this.name = name;
		this.imagename = imagename;
	}
	@ManyToOne(cascade=CascadeType.REFRESH,optional=false)
	@JoinColumn(name="productid")
	@SearchableReference
	public ProductInfo getProduct() {
		return product;
	}
	public void setProduct(ProductInfo product) {
		this.product = product;
	}
	@Id @GeneratedValue
	@SearchableId
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	@Column(length=30,nullable=false)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Column(length=40,nullable=false)
	@SearchableProperty(index = Index.UN_TOKENIZED, store = Store.YES)
	public String getImagename() {
		return imagename;
	}
	public void setImagename(String imagename) {
		this.imagename = imagename;
	}
	@Column(nullable=false)
	public Boolean getVisible() {
		return visible;
	}
	public void setVisible(Boolean visible) {
		this.visible = visible;
	}
	@Transient
	public String getImageFullPath(){
		return "/images/product/"+ this.getProduct().getType().getTypeid()+ "/"+
		this.getProduct().getId()+ "/prototype/"+ this.imagename;
	}
	
	@Transient
	public String getImage140FullPath(){
		image140FullPath = "/images/product/"+ this.getProduct().getType().getTypeid()+ "/"+
		this.getProduct().getId()+ "/140x/"+ this.imagename;
		return image140FullPath;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final ProductStyle other = (ProductStyle) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
}




這裏要特別注意有集合類型要搜索或顯示的時候,兩邊定義的@SearchableReference或 @SearchableComponent必須一致

2.再spring的配置文件中加入以下代碼

Java代碼

  

<bean id="annotationConfiguration"   class="org.compass.annotations.config.CompassAnnotationsConfiguration">   

</bean>   

 <!-- compass Bean  -->   

<bean id="compass" class="org.compass.spring.LocalCompassBean">   

        <property name="compassConfiguration"  

            ref="annotationConfiguration" />   

        <property name="transactionManager" ref="txManager" />   

    <property name="compassSettings">   

            <props>   

 <!-- 定義索引的存儲位置  -->   

<prop key="compass.engine.connection">d:/compass</prop>   

<prop key="compass.transaction.factory">   

                    org.compass.spring.transaction.SpringSyncTransactionFactory   

</prop>   

 <!-- 定義分詞器-->   

<prop key="compass.engine.analyzer.MMAnalyzer.CustomAnalyzer">   

org.mira.lucene.analysis.IK_CAnalyzer   

</prop>   

</props>   

</property>   

        <property name="resourceDirectoryLocations">   

            <list>   

                <value>classpath:net/shopin/bean/product</value>   

            </list>   

        </property>   

  

    </bean>   

  

    <bean id="jpaGpsDevice"  

        class="org.compass.gps.device.jpa.JpaGpsDevice">   

        <property name="name">   

            <value>JpaGpsDevice</value>   

        </property>   

        <property name="entityManagerFactory"  

            ref="entityManagerFactory" />   

        <property name="mirrorDataChanges">   

            <value>true</value>   

        </property>   

    </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>   

                <bean   

                    class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">   

                    <property name="gpsDevice" ref="jpaGpsDevice" />   

                </bean>   

            </list>   

        </property>   

    </bean>   

  

  

    <bean id="compassTemplate"  

        class="org.compass.core.CompassTemplate">   

        <property name="compass" ref="compass" />   

    </bean>   

  

    <!-- 定時重建索引(利用quartz)或隨Spring ApplicationContext啓動而重建索引 -->   

    <bean id="compassIndexBuilder"  

        class="net.shopin.service.search.impl.CompassIndexBuilder"  

        lazy-init="false">   

        <property name="compassGps" ref="compassGps" />   

        <property name="buildIndex" value="true" />   

        <property name="lazyTime" value="5" />   

    </bean>  

<bean id="annotationConfiguration"	class="org.compass.annotations.config.CompassAnnotationsConfiguration">
</bean>
 <!-- compass Bean  -->
<bean id="compass" class="org.compass.spring.LocalCompassBean">
		<property name="compassConfiguration"
			ref="annotationConfiguration" />
		<property name="transactionManager" ref="txManager" />
	<property name="compassSettings">
			<props>
 <!-- 定義索引的存儲位置  -->
<prop key="compass.engine.connection">d:/compass</prop>
<prop key="compass.transaction.factory">
					org.compass.spring.transaction.SpringSyncTransactionFactory
</prop>
 <!-- 定義分詞器-->
<prop key="compass.engine.analyzer.MMAnalyzer.CustomAnalyzer">
org.mira.lucene.analysis.IK_CAnalyzer
</prop>
</props>
</property>
        <property name="resourceDirectoryLocations">
			<list>
				<value>classpath:net/shopin/bean/product</value>
			</list>
		</property>

	</bean>

	<bean id="jpaGpsDevice"
		class="org.compass.gps.device.jpa.JpaGpsDevice">
		<property name="name">
			<value>JpaGpsDevice</value>
		</property>
		<property name="entityManagerFactory"
			ref="entityManagerFactory" />
		<property name="mirrorDataChanges">
			<value>true</value>
		</property>
	</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>
				<bean
					class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">
					<property name="gpsDevice" ref="jpaGpsDevice" />
				</bean>
			</list>
		</property>
	</bean>


	<bean id="compassTemplate"
		class="org.compass.core.CompassTemplate">
		<property name="compass" ref="compass" />
	</bean>

	<!-- 定時重建索引(利用quartz)或隨Spring ApplicationContext啓動而重建索引 -->
	<bean id="compassIndexBuilder"
		class="net.shopin.service.search.impl.CompassIndexBuilder"
		lazy-init="false">
		<property name="compassGps" ref="compassGps" />
		<property name="buildIndex" value="true" />
		<property name="lazyTime" value="5" />
	</bean>



3.自動建立索引的java bean

Java代碼   

/**  

 * 通過quartz定時調度定時重建索引或自動隨Spring ApplicationContext啓動而重建索引的Builder.  

 * 會啓動後延時數秒新開線程調用compassGps.index()函數.  

 * 默認會在Web應用每次啓動時重建索引,可以設置buildIndex屬性爲false來禁止此功能.  

 * 也可以不用本Builder, 編寫手動調用compassGps.index()的代碼.  

 *  

 */  

public class CompassIndexBuilder implements InitializingBean {      

    // 是否需要建立索引,可被設置爲false使本Builder失效.   

    private boolean buildIndex = false;   

  

    // 索引操作線程延時啓動的時間,單位爲秒   

    private int lazyTime = 10;   

  

    // Compass封裝   

    private CompassGps compassGps;   

  

    // 索引線程   

    private Thread indexThread = new Thread() {   

  

        @Override  

        public void run() {   

            try {   

                Thread.sleep(lazyTime * 1000);   

                System.out.println("begin compass index...");   

                long beginTime = System.currentTimeMillis();   

                // 重建索引.   

                // 如果compass實體中定義的索引文件已存在,索引過程中會建立臨時索引,   

                // 索引完成後再進行覆蓋.   

                compassGps.index();   

                long costTime = System.currentTimeMillis() - beginTime;   

                System.out.println("compss index finished.");   

                System.out.println("costed " + costTime + " milliseconds");   

            } catch (InterruptedException e) {   

                e.printStackTrace();   

            }   

        }   

    };   

  

    /**  

     * 實現<code>InitializingBean</code>接口,在完成注入後調用啓動索引線程.  

     *  

     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()  

     */  

    public void afterPropertiesSet() throws Exception {   

        if (buildIndex) {   

            indexThread.setDaemon(true);   

            indexThread.setName("Compass Indexer");   

            indexThread.start();   

        }   

    }   

  

    public void setBuildIndex(boolean buildIndex) {   

        this.buildIndex = buildIndex;   

    }   

  

    public void setLazyTime(int lazyTime) {   

        this.lazyTime = lazyTime;   

    }   

  

    public void setCompassGps(CompassGps compassGps) {   

        this.compassGps = compassGps;   

    }   

}  

/**
 * 通過quartz定時調度定時重建索引或自動隨Spring ApplicationContext啓動而重建索引的Builder.
 * 會啓動後延時數秒新開線程調用compassGps.index()函數.
 * 默認會在Web應用每次啓動時重建索引,可以設置buildIndex屬性爲false來禁止此功能.
 * 也可以不用本Builder, 編寫手動調用compassGps.index()的代碼.
 *
 */
public class CompassIndexBuilder implements InitializingBean {   
    // 是否需要建立索引,可被設置爲false使本Builder失效.
    private boolean buildIndex = false;

    // 索引操作線程延時啓動的時間,單位爲秒
    private int lazyTime = 10;

    // Compass封裝
    private CompassGps compassGps;

    // 索引線程
    private Thread indexThread = new Thread() {

        @Override
        public void run() {
            try {
                Thread.sleep(lazyTime * 1000);
                System.out.println("begin compass index...");
                long beginTime = System.currentTimeMillis();
                // 重建索引.
                // 如果compass實體中定義的索引文件已存在,索引過程中會建立臨時索引,
                // 索引完成後再進行覆蓋.
                compassGps.index();
                long costTime = System.currentTimeMillis() - beginTime;
                System.out.println("compss index finished.");
                System.out.println("costed " + costTime + " milliseconds");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

    /**
     * 實現<code>InitializingBean</code>接口,在完成注入後調用啓動索引線程.
     *
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet() throws Exception {
        if (buildIndex) {
            indexThread.setDaemon(true);
            indexThread.setName("Compass Indexer");
            indexThread.start();
        }
    }

    public void setBuildIndex(boolean buildIndex) {
        this.buildIndex = buildIndex;
    }

    public void setLazyTime(int lazyTime) {
        this.lazyTime = lazyTime;
    }

    public void setCompassGps(CompassGps compassGps) {
        this.compassGps = compassGps;
    }
}



4.建立索引Service 層代碼

Java代碼

  

@Service  

@Transactional  

public class SearchServiceBean extends DaoSupport implements SearchService {   

    @Resource(name = "compass")   

    Compass compass;   

  

/** 創建索引 **/  

public void index(ProductInfo p) {   

  

CompassSession session = compass.openSession();   

CompassTransaction tx = null;   

try {   

    tx = session.beginTransaction();   

    session.create(p);   

    tx.commit();   

catch (Exception e) {   

    if (tx != null) {   

tx.commit();   

    }   

    throw new RuntimeException(e);   

    } finally {   

        if (session != null) {   

        session.close();   

    }   

        }   

    }   

    /** 刪除一條索引 **/  

    public void delete(ProductInfo p) {   

        CompassTemplate ct = new CompassTemplate(compass);   

        ct.delete(p);   

    }   

    /** 更新(重新創建)一條索引 **/  

    public void update(final ProductInfo p) {   

        CompassTemplate ct = new CompassTemplate(compass);   

  

        CompassCallback<Object> action = new CompassCallback<Object>() {   

  

            public Object doInCompass(CompassSession session)   

                    throws CompassException {   

                session.delete(p);   

                session.create(p);   

                return null;   

            }   

  

        };   

  

        ct.execute(action);   

    }   

    /** 索引查詢 **/  

    public List<ProductInfo> find(final String keywords) {   

        CompassTemplate ct = new CompassTemplate(compass);   

        return ct.execute(new CompassCallback<List<ProductInfo>>() {   

  

            public List<ProductInfo> doInCompass(CompassSession session)   

                    throws CompassException {   

                List<ProductInfo> result = new ArrayList<ProductInfo>();   

                CompassQueryBuilder queryBuilder = session.queryBuilder();   

                CompassHits hits = null// session.find(query);   

                /** 在所有字段中查詢 **/  

                CompassQuery allPropertyQuery = queryBuilder.queryString(keywords).toQuery();   

                hits = allPropertyQuery.hits();   

                /** 在指定字段中查詢 **/  

                // CompassQuery query = queryBuilder.term("name", keywords);   

                // hits = query.hits();   

                /** 指定範圍查詢  **/  

//               CompassQuery dateRangeQuery =   

//               queryBuilder.between("postTime",startTime, endTime, true);   

//               hits = queryBuilder.bool()   

//               .addMust(allPropertyQuery)    

//               .addMust(dateRangeQuery)   

//               .toQuery()    

//               .hits();   

//              System.out.println("---------");   

                for (int i = 0; i < hits.length(); i++) {   

                    ProductInfo p = (ProductInfo) hits.data(i);   

                    /** 如果進行高亮的屬性中沒有出現關鍵字, 則返回null  **/  

//                  String ht = hits.highlighter(i).fragment("name");   

//                  if (ht != null) {   

//                      p.setName(ht);   

//                  }   

//                  String hc = hits.highlighter(i).fragment("code");   

//                  if (hc != null) {   

//                      p.setCode(hc);   

//                  }   

                    result.add(p);   

                }   

                return result;   

            }   

        });   

    }  

@Service
@Transactional
public class SearchServiceBean extends DaoSupport implements SearchService {
	@Resource(name = "compass")
	Compass compass;

/** 創建索引 **/
public void index(ProductInfo p) {

CompassSession session = compass.openSession();
CompassTransaction tx = null;
try {
	tx = session.beginTransaction();
	session.create(p);
	tx.commit();
} catch (Exception e) {
	if (tx != null) {
tx.commit();
	}
	throw new RuntimeException(e);
	} finally {
		if (session != null) {
		session.close();
	}
		}
	}
	/** 刪除一條索引 **/
	public void delete(ProductInfo p) {
		CompassTemplate ct = new CompassTemplate(compass);
		ct.delete(p);
	}
	/** 更新(重新創建)一條索引 **/
	public void update(final ProductInfo p) {
		CompassTemplate ct = new CompassTemplate(compass);

		CompassCallback<Object> action = new CompassCallback<Object>() {

			public Object doInCompass(CompassSession session)
					throws CompassException {
				session.delete(p);
				session.create(p);
				return null;
			}

		};

		ct.execute(action);
	}
	/** 索引查詢 **/
	public List<ProductInfo> find(final String keywords) {
		CompassTemplate ct = new CompassTemplate(compass);
		return ct.execute(new CompassCallback<List<ProductInfo>>() {

			public List<ProductInfo> doInCompass(CompassSession session)
					throws CompassException {
				List<ProductInfo> result = new ArrayList<ProductInfo>();
				CompassQueryBuilder queryBuilder = session.queryBuilder();
				CompassHits hits = null; // session.find(query);
				/** 在所有字段中查詢 **/
				CompassQuery allPropertyQuery = queryBuilder.queryString(keywords).toQuery();
				hits = allPropertyQuery.hits();
				/** 在指定字段中查詢 **/
				// CompassQuery query = queryBuilder.term("name", keywords);
				// hits = query.hits();
				/** 指定範圍查詢  **/
//				 CompassQuery dateRangeQuery =
//				 queryBuilder.between("postTime",startTime, endTime, true);
//				 hits = queryBuilder.bool()
//				 .addMust(allPropertyQuery) 
//				 .addMust(dateRangeQuery)
//				 .toQuery() 
//				 .hits();
//				System.out.println("---------");
				for (int i = 0; i < hits.length(); i++) {
					ProductInfo p = (ProductInfo) hits.data(i);
					/** 如果進行高亮的屬性中沒有出現關鍵字, 則返回null  **/
//					String ht = hits.highlighter(i).fragment("name");
//					if (ht != null) {
//						p.setName(ht);
//					}
//					String hc = hits.highlighter(i).fragment("code");
//					if (hc != null) {
//						p.setCode(hc);
//					}
					result.add(p);
				}
				return result;
			}
		});
	}



控制層

Java代碼

@Controller("/search/gosearch")   

public class SearchAction extends Action {   

    @Resource(name = "searchServiceBean")   

    private SearchService SearchService;   

  

    @Override  

    public ActionForward execute(ActionMapping mapping, ActionForm form,   

            HttpServletRequest request, HttpServletResponse response)   

            throws Exception {   

        String keywords=request.getParameter("word").trim();   

        if(keywords==null||"".equals(keywords)){   

            return mapping.findForward("noproduct");   

        }   

        System.out.println("------"+keywords);   

        List<ProductInfo> list = SearchService.find(keywords);   

        request.setAttribute("word", keywords);   

        request.setAttribute("product",list);   

        if(list.isEmpty()){   

            return mapping.findForward("noproduct");   

        }else{   

            return mapping.findForward("list");   

               

        }   

    }   

}  

@Controller("/search/gosearch")
public class SearchAction extends Action {
	@Resource(name = "searchServiceBean")
	private SearchService SearchService;

	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		String keywords=request.getParameter("word").trim();
		if(keywords==null||"".equals(keywords)){
			return mapping.findForward("noproduct");
		}
		System.out.println("------"+keywords);
		List<ProductInfo> list = SearchService.find(keywords);
		request.setAttribute("word", keywords);
		request.setAttribute("product",list);
        if(list.isEmpty()){
        	return mapping.findForward("noproduct");
        }else{
        	return mapping.findForward("list");
        	
        }
	}
}



junit測試

Java代碼

public class SearchTest {   

       

    private static AbstractApplicationContext context;   

    @BeforeClass  

    public static void setUpBeforeClass() throws Exception {   

        try {   

            context = new ClassPathXmlApplicationContext("beans.xml");   

        } catch (Exception e) {   

            e.printStackTrace();   

        }   

    }   

       

    @Test  

    public void testDelete() {   

        SearchService searchService = (SearchService) context   

        .getBean("searchServiceBean");   

        ProductInfo p = new ProductInfo(2);   

        searchService.delete(p);   

    }   

  

    @Test  

    public void createIndex(){   

        SearchService searchService = (SearchService) context   

        .getBean("searchServiceBean");   

        ProductInfoService productInfoService = (ProductInfoService) context   

        .getBean("productInfoServiceBean");   

        List<ProductInfo> list=productInfoService.getAllProduct();   

        for(ProductInfo productInfo:list){   

//          System.out.println("-------"+productInfo.getName());   

            searchService.index(productInfo);   

        }   

    }   

       

    @Test  

    public void testSearch() {   

        SearchService searchService = (SearchService) context   

        .getBean("searchServiceBean");   

        String query = "手機";   

        List<ProductInfo> ProductInfos;   

       

            ProductInfos = searchService.find(query);   

            for (ProductInfo p : ProductInfos) {   

                System.out.println(p.getName());   

            }   

        System.out.println("------------");   

    }   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章