compass学习笔记

以下是鄙人在学习compass所做的笔记(如果鄙人写的不是很清楚的话,可以从电驴或者迅雷上搜索v521刘伟老师的compass学习视频)。系统框架采用Struts2.1.6+Spring2.5.4+Hibernate3+compass2.1.0,JDK版本采用6.0的。

首先,需要将将SSH整合好。具体的我不在此说明,可以在google上进行搜索。我将重点说明compass如何与SSH进行整合。

使用compass框架,首先需要进行compass关于实体类的映射。compass在其文档中说明,一般是在实体类相对应的*.cpm.xml中进行配置的。但是在开发中,我们可以借助jdk关于标注的新特性,将此文件省略。具体代码如下所示:

package com.zhou.model; import java.io.Serializable; import org.compass.annotations.Searchable; import org.compass.annotations.SearchableId; import org.compass.annotations.SearchableProperty; @Searchable public class Product implements Serializable { private static final long serialVersionUID = -3148838659193709682L; //Field @SearchableId private String id; @SearchableProperty(name="name") private String name; @SearchableProperty(name="price") private Integer price; @SearchableProperty(name="brand") private String brand; @SearchableProperty(name="description") private String description; // Constructors /** default constructor */ public Product() { } /** full constructor */ public Product(String name, Integer price, String brand, String description) { this.name = name; this.price = price; this.brand = brand; this.description = description; } // Property accessors public String getId() { return this.id; } public void setId(String id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Integer getPrice() { return this.price; } public void setPrice(Integer price) { this.price = price; } public String getBrand() { return this.brand; } public void setBrand(String brand) { this.brand = brand; } public String getDescription() { return this.description; } public void setDescription(String description) { this.description = description; } }

如代码所示,实体类的类声明和属性声明分别加入了相应的标注。public class前面的“@Searchable”表示此类可以被索引,也就是此类对应的数据库可以被索引。属性id前的“@SearchableId”表示索引建立的id。其他属性前面的“@SearchableProperty(name="name")”表示此字段可以被索引、被检索。name=“name”表示此字段被索引后的名称。在检索类中,可以根据此名字指定搜索的字段名称。

建立索引的类(CompassIndexBuilder.java)

package com.zhou.service.impl; import java.util.Date; import org.compass.gps.CompassGps; import org.springframework.beans.factory.InitializingBean; public class CompassIndexBuilder implements InitializingBean { private boolean buildIndex = false; private int lazyTime = 5; private CompassGps compassGps; private Thread indexThread = new Thread() { public void run() { try { Thread.sleep(lazyTime * 1000); System.out.println("begin compass index..."); long beginTime = System.currentTimeMillis(); compassGps.index(); long costTime = System.currentTimeMillis() - beginTime; System.out.println("compss index finished."); System.out.println("costed " + costTime + " milliseconds"); } catch (InterruptedException e) { e.printStackTrace(); } } }; public void afterPropertiesSet() throws Exception { System.out.println(new Date()+"调用"); 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; } }

详细的解释可以观看视频,在此不再说明。

compass的配置写在同一个文件(applicationContext-compass)中,以便同一管理。内容如下:

<?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"> <!-- 如果使用jdk标注新特性,此处必须有的 --> <bean id="annotationConfiguration" class="org.compass.annotations.config.CompassAnnotationsConfiguration"> </bean> <bean id="compass" class="org.compass.spring.LocalCompassBean"> <property name="resourceDirectoryLocations"> <list> <value>classpath:com/zhou</value> </list> </property> <property name="connection"> <value>/lucene/indexes</value> </property> <property name="classMappings"> <list> <value>com.zhou.model.Product</value> </list> </property> <property name="compassConfiguration" ref="annotationConfiguration" /> <property name="compassSettings"> <props> <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> <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" 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="hibernateGpsDevice" /> </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="com.zhou.service.impl.CompassIndexBuilder" lazy-init="false"> <property name="compassGps" ref="compassGps" /> <property name="buildIndex" value="true" /> <property name="lazyTime" value="5" /> </bean> </beans>

在业务层进行数据检索的代码如下:

public List<Product> searchProducts(String queryString) { List<Product> products = new ArrayList<Product>(); Compass compass = compassTemplate.getCompass(); CompassSession session = compass.openSession(); CompassHits hits = session.queryBuilder().queryString( "name:" + queryString).toQuery().hits(); System.out.println("---------------------------------------------"); System.out.println("queryString=" + queryString); System.out.println("结果个数=" + hits.length()); for (int i = 0; i < hits.length(); i++) { Product hit = (Product) hits.data(i); String ht = hits.highlighter(i).fragment("name"); if (null != ht) { hit.setName(ht); } products.add(hit); } return products; }

以上是关键部分的说明。在bs层中的检索方法searchProducts(String queryString)中,有很多地方需要深入的思考一下。比如:在“CompassHits hits = session.queryBuilder().queryString("name:" + queryString).toQuery().hits();”中的“name”就是至前面实体类中的“@SearchableProperty(name="name")”中“name”的值,表示只对该字段进行检索。又比如涉及到结果分页显示的话,该如何封装返回的结果。究竟是一次全部封装到List中还是每页显示n条就封装n条,翻页的时候继续hit呢?有待深入思考。

附件为样例程序,但是相关的jar包太大了,无法上传!需要自己查找。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值