hibernate search 例子

1、开发环境:spring2.5、hibernate3.3.1GA、hibernateSearch3.1.0GA;

2、开发是基于maven上开发的,首先新建一个web工程,添加maven支持,在pom.xml中添加一下几个依赖包:

 <dependencies>      
  <dependency>  
      <groupId>org.apache.openejb</groupId>  
      <artifactId>javaee-api</artifactId>  
      <version>5.0-1</version>  
      <scope>provided</scope>  
    </dependency>  
        <dependency>    
    <groupId>org.hibernate</groupId>    
    <artifactId>hibernate-search</artifactId>    
    <version>3.1.0.GA</version>    
    </dependency>    
    <dependency>    
        <groupId>org.hibernate</groupId>    
        <artifactId>hibernate-annotations</artifactId>    
        <version>3.4.0.GA</version>    
    </dependency>      
      
<!-- hibernate framework end -->    
       
<!-- lucene start -->    
<dependency>    
    <groupId>org.apache.lucene</groupId>    
    <artifactId>lucene-analyzers</artifactId>    
    <version>3.0.1</version>    
</dependency>    
<dependency>    
    <groupId>org.apache.lucene</groupId>    
    <artifactId>lucene-highlighter</artifactId>    
    <version>3.0.1</version>    
</dependency>    
  </dependencies>  
<dependencies>    
  <dependency>
      <groupId>org.apache.openejb</groupId>
      <artifactId>javaee-api</artifactId>
      <version>5.0-1</version>
      <scope>provided</scope>
    </dependency>
        <dependency>  
    <groupId>org.hibernate</groupId>  
    <artifactId>hibernate-search</artifactId>  
    <version>3.1.0.GA</version>  
	</dependency>  
	<dependency>  
	    <groupId>org.hibernate</groupId>  
	    <artifactId>hibernate-annotations</artifactId>  
	    <version>3.4.0.GA</version>  
	</dependency>    
	
<!-- hibernate framework end -->  
     
<!-- lucene start -->  
<dependency>  
    <groupId>org.apache.lucene</groupId>  
    <artifactId>lucene-analyzers</artifactId>  
    <version>3.0.1</version>  
</dependency>  
<dependency>  
    <groupId>org.apache.lucene</groupId>  
    <artifactId>lucene-highlighter</artifactId>  
    <version>3.0.1</version>  
</dependency>  
  </dependencies>



其他就是hibernate+spring的配置了;
注意一点的就是在配置文件hibernate的属性后面加上索引的监听和索引存放的位置,如:

<!-- Spring管理Hibernate的Mapping对象 -->  
    <bean id="sessionFactory"  
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="dataSource">  
            <ref bean="dataSource" />  
        </property>  
        <property name="hibernateProperties">  
            <props>  
                <prop key="hibernate.dialect">  
                    ${hibernate.dialect}  
                </prop>  
                <prop key="hibernate.hbm2ddl.auto">  
                    ${hibernate.hbm2ddl.auto}  
                </prop>  
                <prop key="hibernate.show_sql">  
                    ${hibernate.show_sql}  
                </prop>  
                <prop key="hibernate.use_sql_comments">  
                    ${hibernate.use_sql_comments}  
                </prop>  
                <prop key="hibernate.use_outer_join">  
                    ${hibernate.use_outer_join}  
                </prop>  
                <prop key="hibernate.current_session_context_class">  
                    ${hibernate.current.session.context.class}  
                </prop>  
                <prop key="connection.autoReconnect">  
                    ${connection.autoReconnect}  
                </prop>   
                <prop key="connection.autoReconnectForPools">  
                    ${connection.autoReconnectForPools}  
                </prop>   
                <prop key="connection.is-connection-validation-required">  
                    ${connection.is-connection-validation-required}  
                </prop>   
                  
                <!-- 索引配置 -->  
                <prop key="hibernate.search.default.directory_provider">  
                    org.hibernate.search.store.FSDirectoryProvider  
                </prop>  
                <prop key="hibernate.search.default.indexBase">  
                    d:/JAVA/hibernateIndex  
                </prop>  
                   
            </props>  
        </property>  
          
        <!-- 索引配置-->  
        <property name="eventListeners">    
            <map>    
                <entry key="post-update">    
                    <bean class="org.hibernate.search.event.FullTextIndexEventListener" />    
                </entry>    
                <entry key="post-insert">    
                    <bean class="org.hibernate.search.event.FullTextIndexEventListener" />    
                </entry>    
                <entry key="post-delete">    
                    <bean class="org.hibernate.search.event.FullTextIndexEventListener" />    
                </entry>    
            </map>    
        </property>  
          
        <property name="mappingDirectoryLocations">  
            <list>  
                <value>${hibernate.mappingDirectoryLocations}</value>  
            </list>  
        </property>  
    </bean>  
<!-- Spring管理Hibernate的Mapping对象 -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					${hibernate.dialect}
				</prop>
				<prop key="hibernate.hbm2ddl.auto">
					${hibernate.hbm2ddl.auto}
				</prop>
				<prop key="hibernate.show_sql">
					${hibernate.show_sql}
				</prop>
				<prop key="hibernate.use_sql_comments">
					${hibernate.use_sql_comments}
				</prop>
				<prop key="hibernate.use_outer_join">
					${hibernate.use_outer_join}
				</prop>
				<prop key="hibernate.current_session_context_class">
					${hibernate.current.session.context.class}
				</prop>
				<prop key="connection.autoReconnect">
					${connection.autoReconnect}
				</prop> 
        		<prop key="connection.autoReconnectForPools">
        			${connection.autoReconnectForPools}
        		</prop> 
        		<prop key="connection.is-connection-validation-required">
        			${connection.is-connection-validation-required}
        		</prop> 
        		
        		<!-- 索引配置 -->
        		<prop key="hibernate.search.default.directory_provider">
					org.hibernate.search.store.FSDirectoryProvider
				</prop>
				<prop key="hibernate.search.default.indexBase">
					d:/JAVA/hibernateIndex
				</prop>
				 
			</props>
		</property>
		
		<!-- 索引配置-->
		<property name="eventListeners">  
            <map>  
                <entry key="post-update">  
                    <bean class="org.hibernate.search.event.FullTextIndexEventListener" />  
                </entry>  
                <entry key="post-insert">  
                    <bean class="org.hibernate.search.event.FullTextIndexEventListener" />  
                </entry>  
                <entry key="post-delete">  
                    <bean class="org.hibernate.search.event.FullTextIndexEventListener" />  
                </entry>  
            </map>  
		</property>
		
		<property name="mappingDirectoryLocations">
			<list>
				<value>${hibernate.mappingDirectoryLocations}</value>
			</list>
		</property>
	</bean>



这时启动如果报slf4j错误,可能是你的slf4j包冲突,需要把你lib里相关的jar包删了,在maven支持中还剩下slf4j-api-1.4.2.jar,需要导入slf4j-logging-1.4.2.jar包,如果导入更高版可能会报错,这个包在百度搜slf4j就能进入它的官网,很容易找到;

这个时候启动如果不报错,那成功一半了;接下来就是配置实体类了,比如一个商城系统要对订单建索引,实体类如(给出关键部分代码):

@Entity  
@Indexed(index="shopOrders")  
public class ShopOrders  implements java.io.Serializable {  
  
  
    // Fields      
  
     @DocumentId  
     private String id;  
     private Integer uid;  
     @Field(index=Index.TOKENIZED,store=Store.YES)  
     private String username;  
     @Field(index=Index.UN_TOKENIZED,store=Store.YES)  
     private Integer isDelete;  
@Entity
@Indexed(index="shopOrders")
public class ShopOrders  implements java.io.Serializable {


    // Fields    

     @DocumentId
     private String id;
     private Integer uid;
     @Field(index=Index.TOKENIZED,store=Store.YES)
     private String username;
     @Field(index=Index.UN_TOKENIZED,store=Store.YES)
     private Integer isDelete;



这个时候启动你会发现你指定的路径下已经有了一个shopOrders文件夹,如果这个时候去搜索是搜索不到的,还没有初始化数据;
以下是数据初始化和查询的代码:

import java.util.Date;  
import java.util.List;  
  
import org.apache.lucene.analysis.standard.StandardAnalyzer;  
import org.apache.lucene.queryParser.MultiFieldQueryParser;  
import org.apache.lucene.queryParser.QueryParser;  
import org.apache.lucene.search.BooleanClause;  
import org.apache.lucene.search.BooleanQuery;  
import org.apache.lucene.search.Query;  
import org.hibernate.CacheMode;  
import org.hibernate.FlushMode;  
import org.hibernate.ScrollMode;  
import org.hibernate.ScrollableResults;  
import org.hibernate.Session;  
import org.hibernate.SessionFactory;  
import org.hibernate.search.FullTextQuery;  
import org.hibernate.search.FullTextSession;  
import org.hibernate.search.Search;  
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;  
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;  
  
import com.china.fung.hibernate.pojo.shop.ShopOrders;  
  
public class Dao extends HibernateDaoSupport {  
  
    private static SessionFactory sessionFactory;  
    private static Session session = null;  
    private static LocalSessionFactoryBean factoryBean = null;  
  
    public void getMySession() throws Exception {  
        sessionFactory = this.getHibernateTemplate().getSessionFactory();  
        session = sessionFactory.openSession();  
    }  
  
    public List search(String keyword) throws Exception {  
        this.getMySession();  
        BooleanQuery.setMaxClauseCount(100000);  
        BooleanQuery booleanQuery = new BooleanQuery();  
        StandardAnalyzer analyzer=new StandardAnalyzer();  
        // 基本关键词搜索  
        String[] searchFields = new String[] { "username" };//成员变量  
        MultiFieldQueryParser queryParser = new MultiFieldQueryParser(  
                searchFields,analyzer);  
        queryParser.setDefaultOperator(QueryParser.Operator.AND);  
        Query query = queryParser.parse(keyword);  
        booleanQuery.add(query,BooleanClause.Occur.MUST);  
          
        QueryParser parse=new QueryParser("isDelete",analyzer);  
        Query query1=parse.parse("0");  
        parse.setDefaultOperator(QueryParser.Operator.AND);  
        booleanQuery.add(query1,BooleanClause.Occur.MUST);  
  
        FullTextSession fullSession = Search.getFullTextSession(session);  
        FullTextQuery fullQuery = fullSession.createFullTextQuery(booleanQuery,  
                ShopOrders.class);  
        int size = fullQuery.getResultSize();  
        System.out.println("size:" + size);  
          
        return fullQuery.list();  
    }  
      
     public void createIndexByHibernateSearch() throws Exception{  
         this.getMySession();  
          long startTime = new Date().getTime();  
          int BATCH_SIZE = 1000;  
          FullTextSession s = Search.getFullTextSession(session);  
  
          // Transaction tr = s.beginTransaction();  
          s.setFlushMode(FlushMode.MANUAL);  
          s.setCacheMode(CacheMode.IGNORE);  
          ScrollableResults results = s.createQuery("from ShopOrders").setFetchSize(BATCH_SIZE).scroll(ScrollMode.FORWARD_ONLY);  
          int index = 0;  
          while (results.next()) {  
           index++;  
           s.index(results.get(0)); // index each element  
           if (index % BATCH_SIZE == 0) {  
            // s.flushToIndexes(); //apply changes to indexes  
            s.clear(); // clear since the queue is processed  
           }  
          }  
          s.clear();  
          long endTime = new Date().getTime();  
          logger.warn("建立Product索引 , 这花费了" + (endTime - startTime) + " 毫秒来把文档增加到索引里面去!");  
          // tr.commit();  
  
         }  
      
  
}  
import java.util.Date;
import java.util.List;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.china.fung.hibernate.pojo.shop.ShopOrders;

public class Dao extends HibernateDaoSupport {

	private static SessionFactory sessionFactory;
	private static Session session = null;
	private static LocalSessionFactoryBean factoryBean = null;

	public void getMySession() throws Exception {
		sessionFactory = this.getHibernateTemplate().getSessionFactory();
		session = sessionFactory.openSession();
	}

	public List search(String keyword) throws Exception {
		this.getMySession();
		BooleanQuery.setMaxClauseCount(100000);
		BooleanQuery booleanQuery = new BooleanQuery();
		StandardAnalyzer analyzer=new StandardAnalyzer();
		// 基本关键词搜索
		String[] searchFields = new String[] { "username" };//成员变量
		MultiFieldQueryParser queryParser = new MultiFieldQueryParser(
				searchFields,analyzer);
		queryParser.setDefaultOperator(QueryParser.Operator.AND);
		Query query = queryParser.parse(keyword);
		booleanQuery.add(query,BooleanClause.Occur.MUST);
		
		QueryParser parse=new QueryParser("isDelete",analyzer);
		Query query1=parse.parse("0");
		parse.setDefaultOperator(QueryParser.Operator.AND);
		booleanQuery.add(query1,BooleanClause.Occur.MUST);

		FullTextSession fullSession = Search.getFullTextSession(session);
		FullTextQuery fullQuery = fullSession.createFullTextQuery(booleanQuery,
				ShopOrders.class);
		int size = fullQuery.getResultSize();
		System.out.println("size:" + size);
		
		return fullQuery.list();
	}
	
	 public void createIndexByHibernateSearch() throws Exception{
		 this.getMySession();
		  long startTime = new Date().getTime();
		  int BATCH_SIZE = 1000;
		  FullTextSession s = Search.getFullTextSession(session);

		  // Transaction tr = s.beginTransaction();
		  s.setFlushMode(FlushMode.MANUAL);
		  s.setCacheMode(CacheMode.IGNORE);
		  ScrollableResults results = s.createQuery("from ShopOrders").setFetchSize(BATCH_SIZE).scroll(ScrollMode.FORWARD_ONLY);
		  int index = 0;
		  while (results.next()) {
		   index++;
		   s.index(results.get(0)); // index each element
		   if (index % BATCH_SIZE == 0) {
		    // s.flushToIndexes(); //apply changes to indexes
		    s.clear(); // clear since the queue is processed
		   }
		  }
		  s.clear();
		  long endTime = new Date().getTime();
		  logger.warn("建立Product索引 , 这花费了" + (endTime - startTime) + " 毫秒来把文档增加到索引里面去!");
		  // tr.commit();

		 }
	

}



好了,到这基本就完事了,只需要在service里调用就行了,别忘了,先调用createIndexByHibernateSearch方法初始化(一次就行),再调用search方法搜索;

相关推荐