繌子 2013-08-21
基于Spring的HibernateSearch全文检索功能示例
http://hi.baidu.com/zwnlavmytfbjnwd/item/e98bfc516cd72cced3e10c41
HibernateSearch牛刀小试http://blog.csdn.net/yanghuw/article/details/1808011,蛮详细的。
HibernateSearch全面概述http://developer.51cto.com/art/200909/154278.htm
HibernateSearch项目的主要特性包含以下几个方面:
1.Lucene集成——作为强大高效的检索引擎,Lucene的美名早已久经考验了;
2.数据的自动插入和更新——当一个对象通过Hibernate添加或更新时,索引也会相应进行透明的更新;
3.支持众多复杂的搜索方式——可快速的使用通配符进行搜索,以及多关键词全文检索(multi-wordtextsearches)和近似或同义词搜索(approximation/synonymsearches),或根据相关性排列搜索结果;
4.搜索集群(SearchClustering)——HibernateSearch提供了内建搜索集群解决方案,其中包括一个基于JMS的异步查询和索引系统;
5.对LuceneAPI接口的直接调用——如果用户打算处理某些特别复杂的问题,可以在查询中直接使用Lucene提供的API接口;
6.对Lucene的自动管理——HibernateSearch可以管理并优化Lucene的索引,并且非常高效地使用Lucene的API接口。
HibernateSearch相关的Annotation主要有三个:
@Indexed标识需要进行索引的对象,属性:index指定索引文件的路径
@DocumentId用于标示实体类中的唯一的属性保存在索引文件中,是当进行全文检索时可以这个唯一的属性来区分索引中其他实体对象,一般使用实体类中的主键属性
@Field标注在类的get属性上,标识一个索引的Field属性:index指定是否索引,与Lucene相同
store指定是否索引,与Lucene相同
name指定Field的name,默认为类属性的名称
analyzer指定分析器
另外@IndexedEmbedded与@ContainedIn用于关联类之间的索引
@IndexedEmbedded有两个属性,一个prefix指定关联的前缀,一个depth指定关联的深度
数据库:Oracle9i
JDBC驱动:OJDBC14
开发环境:Eclipse-JEE
Spring版本:Spring2.0.6
Hibernate版本:HibernateCore3.2.5/HibernateAnnotation3.3.0/HibernateValidator3.0.0/HibernateSearch3.0.0Beta4
//jdbc.properties(JDBC配置文件)
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.0.3:1521:itone
jdbc.username=test
jdbc.password=test
//hibernate.properties(Hibernate配置文件)
hibernate.dialect=org.hibernate.dialect.Oracle9Dialect
hibernate.show_sql=false
hibernate.cache.use_query_cache=true
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
hibernate.hbm2ddl.auto=update
######以下是HibernateSearch的简单配置######
hibernate.search.default.directory_provider=org.hibernate.search.store.FSDirectoryProvider
hibernate.search.default.indexBase=E:/indexes
//Foo.java(HibernatePOJO文件)
@Entity
@Table(name="search_foo")
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Indexed(index="search_foo")
publicclassFooimplementsSerializable{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@DocumentId
privateIntegerid;
@Column(nullable=false,length=256)
@Field(name="name",index=Index.TOKENIZED,store=Store.YES)
privateStringname;
@Lob
@Field(name="content",index=Index.TOKENIZED,store=Store.YES)
privateStringcontent;
@Column(name="post_time",nullable=false)
@DateBridge(resolution=Resolution.DAY)
privateCalendarpostTime;
publicIntegergetId(){
returnid;
}
publicvoidsetId(Integerid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetContent(){
returncontent;
}
publicvoidsetContent(Stringcontent){
this.content=content;
}
publicCalendargetPostTime(){
returnpostTime;
}
publicvoidsetPostTime(CalendarpostTime){
this.postTime=postTime;
}
}
//hibernate.cfg.xml(Hibernate配置文件)
<?xmlversion="1.0"?>
<!DOCTYPEhibernate-configurationPUBLIC
"-//Hibernate/HibernateConfigurationDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mappingclass="com.itone.search.pojo.Foo"/>
</session-factory>
</hibernate-configuration>
//applicationContext-conf.xml(加载.properties文件的配置文件)
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">
<beansdefault-autowire="byName">
<beanid="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"lazy-init="false">
<propertyname="locations">
<list>
<value>classpath*:jdbc.properties</value>
<value>classpath*:hibernate.properties</value>
</list>
</property>
</bean>
</beans>
//applicationContext-database.xml(数据源及SessionFactory定义文件)
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">
<beansdefault-autowire="byName">
<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">
<propertyname="driverClassName"value="${jdbc.driverClassName}"/>
<propertyname="url"value="${jdbc.url}"/>
<propertyname="username"value="${jdbc.username}"/>
<propertyname="password"value="${jdbc.password}"/>
</bean>
<beanid="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
<propertyname="configLocation"value="/WEB-INF/classes/hibernate.cfg.xml"/>
<propertyname="hibernateProperties">
<props>
<propkey="hibernate.dialect">${hibernate.dialect}</prop>
<propkey="hibernate.show_sql">${hibernate.show_sql}</prop>
<propkey="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<propkey="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
<propkey="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<propkey="hibernate.search.default.directory_provider">${hibernate.search.default.directory_provider}</prop>
<propkey="hibernate.search.default.indexBase">${hibernate.search.default.indexBase}</prop>
</props>
</property>
</bean>
<beanid="jdbcExceptionTranslator"class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator"/>
<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"/>
<beanid="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"/>
</beans>
//applicationContext-manager.xml(Manager定义文件)
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">
<beansdefault-autowire="byName">
<beanid="baseTxService"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"abstract="true">
<propertyname="proxyTargetClass"value="true"/>
<propertyname="transactionAttributes">
<props>
<propkey="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!--Authenticationmanagerforloginandrolechecking-->
<beanid="fooManager"parent="baseTxService">
<propertyname="target">
<beanclass="com.itone.search.manager.FooManager"/>
</property>
</bean>
</beans>
//SpringMVC、Log4j、EHCache配置略
......
//FooManager.java(做全文检索示例)
packagecom.itone.search.manager;
importjava.util.List;
importorg.apache.lucene.analysis.StopAnalyzer;
importorg.apache.lucene.queryParser.QueryParser;
importorg.apache.lucene.search.Query;
importorg.hibernate.search.FullTextQuery;
importorg.hibernate.search.FullTextSession;
importcom.itone.search.pojo.Foo;
publicclassFooManagerextendsBaseManager<Foo>{
@SuppressWarnings("unchecked")
publicvoidtestQuery()throwsException{
QueryParserparser=newQueryParser("name",newStopAnalyzer());
QueryluceneQuery=parser.parse("name:Jack");
FullTextSessions=Search.createFullTextSession(getSession());
FullTextQueryquery=s.createFullTextQuery(luceneQuery,Foo.class);
List<Foo>result=query.list();
for(Foof:result){
System.out.println("ID:"+f.getId());
System.out.println("NAME:"+f.getName());
System.out.println("CONTENT:"+f.getContent());
System.out.println("POSTTIME:"+f.getPostTime());
}
}
}