基于Spring的Hibernate Search全文检索功能示例

xiaoxiaoabc 2013-06-16

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指定关联的深度

其他注解说明:http://sin90lzc.iteye.com/blog/1106258

数据库: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")
public class Foo implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@DocumentId
private Integer id;

@Column(nullable = false, length = 256)
@Field(name = "name", index = Index.TOKENIZED, store = Store.YES)
private String name;

@Lob
@Field(name = "content", index = Index.TOKENIZED, store = Store.YES)
private String content;

@Column(name = "post_time", nullable = false)
@DateBridge(resolution = Resolution.DAY)
private Calendar postTime;
public Integer getId() {
     return id;
}
public void setId(Integer id) {
     this.id = id;
}
public String getName() {
     return name;
}
public void setName(String name) {
     this.name = name;
}
public String getContent() {
     return content;
}
public void setContent(String content) {
     this.content = content;
}
public Calendar getPostTime() {
     return postTime;
}
public void setPostTime(Calendar postTime) {
     this.postTime = postTime;
}
}

//hibernate.cfg.xml(Hibernate配置文件)

<?xml version="1.0"?>
<!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.itone.search.pojo.Foo"/>
  
</session-factory>

</hibernate-configuration>

//applicationContext-conf.xml(加载.properties文件的配置文件)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" lazy-init="false">
     <property name="locations">
      <list>
       <value>classpath*:jdbc.properties</value>
       <value>classpath*:hibernate.properties</value>
      </list>
     </property>
</bean>
</beans>

//applicationContext-database.xml(数据源及SessionFactory定义文件)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
     <property name="driverClassName" value="${jdbc.driverClassName}"/>
     <property name="url" value="${jdbc.url}"/>
     <property name="username" value="${jdbc.username}"/>
     <property name="password" value="${jdbc.password}"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
     <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
     <property name="configLocation" value="/WEB-INF/classes/hibernate.cfg.xml"/>
     <property name="hibernateProperties">
      <props>
       <prop key="hibernate.dialect">${hibernate.dialect}</prop>
       <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
       <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
       <prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
       <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
    
       <prop key="hibernate.search.default.directory_provider">${hibernate.search.default.directory_provider}</prop>
       <prop key="hibernate.search.default.indexBase">${hibernate.search.default.indexBase}</prop>
      </props>
     </property>
</bean>
<bean id="jdbcExceptionTranslator" class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"/>
</beans>

//applicationContext-manager.xml(Manager定义文件)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="baseTxService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
     <property name="proxyTargetClass" value="true"/>
           <property name="transactionAttributes">
      <props>
       <prop key="*">PROPAGATION_REQUIRED</prop>
      </props>
     </property>
</bean>

<!-- Authentication manager for login and role checking -->
<bean id="fooManager" parent="baseTxService">
     <property name="target">
      <bean class="com.itone.search.manager.FooManager"/>
     </property>
</bean>

</beans>

//SpringMVC、Log4j、EHCache配置略

......

//FooManager.java(做全文检索示例)

package com.itone.search.manager;
import java.util.List;
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import com.itone.search.pojo.Foo;
public class FooManager extends BaseManager<Foo> {

@SuppressWarnings("unchecked")
public void testQuery() throws Exception {
     QueryParser parser = new QueryParser("name", new StopAnalyzer());
     Query luceneQuery = parser.parse("name:Jack");
     FullTextSession s = Search.createFullTextSession(getSession());
     FullTextQuery query = s.createFullTextQuery(luceneQuery, Foo.class);
     List<Foo> result = query.list();
     for(Foo f : 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());
     }
}
}

相关推荐