`
stenlylee
  • 浏览: 263501 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Hibernate Search, Lucene 与 JBoss Seam

阅读更多

原文地址:http://www.abstractec.co.uk/blog/index.php?itemid=57

在这篇文章里,我将描述如何将Hibernate Search添加到JBoss Seam里面。

首先,我们需要将相关配置添加到persistence.xml中,如下:

<!-- use a file system based index -->

<property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider" />

<!-- directory where the indexes will be stored -->

<property name="hibernate.search.default.indexBase" value="[/path/to/your/location/directory]" />

<property name="hibernate.ejb.event.post-insert" value="org.hibernate.search.event.FullTextIndexEventListener" />

<property name="hibernate.ejb.event.post-update" value="org.hibernate.search.event.FullTextIndexEventListener" />

<property name="hibernate.ejb.event.post-delete" value="org.hibernate.search.event.FullTextIndexEventListener" />

 
这样我们就设置好了类路径、索引路径、索引操作监听器路径。下面,我们需要添加hibernate-search.jar、hibernate-commons-annotations.jar和lucene-core.jar到你的ear里面。

好了,现在,我们需要告诉Hibernate Search哪个对象被索引,并且我们会对哪些属性感兴趣。

@Entity
@Name("product")
@Indexed
public class Product implements Serializable {
    static final long serialVersionUID = 1l;

    @Id @GeneratedValue @DocumentId
    private Long id;

     @NotNull
    @Field(index = Index.TOKENIZED)
    private String name;

    @NotNull
    @Field(index = Index.TOKENIZED)
    private String description;
    // getters and setters

}

 
@Indexed注解用来告诉Hibernate Search该持久类是拥有索引的。@DocumentId注解用来标明这个属性是这个对象的ID,并且未被编入索引。此外,我们还有两个属性,分别是name和description。这两个属性都用@Field标注,这样Hibernate Search就被允许分析处理这两个属性。其他可选的属性有Index.NO(不要被分析)、Index.UN_TOKENIZED(不要被分析器预先处理)、Index.NO_NORM(不需要存储的普通属性)。

 

现在,我们已经拥有了Lucene的所有索引,我们还需要一个搜索的方法。所以我们需要建立一个SearchManager类。

@Name("SearchManager")
public class SearchManager {

    @In
    private FullTextEntityManager entityManager;
    private String searchPattern;

    // getters and setters for searchPattern

    public List getResults() {
         Map boostFields = new HashMap(2);
         // increase the importance of the name field 
         // over the other product fields
         boostFields.put("name", 4f); 
         String[] productFields = {"name", "description"};
         QueryParser parser = new MultiFieldQueryParser(productFields, new StandardAnalyzer(), boostFields);
         parser.setAllowLeadingWildcard(true);
       Query luceneQuery;
       try {
            luceneQuery = parser.parse(searchPattern);
        } catch (ParseException pe) {
            log.error("found a problem in search", pe);
            return null;
        }

        // extract the products    

        List products = 
            entityManager.createFullTextQuery(luceneQuery, Product.class).
            setMaxResults(20).getResultList();

        return products;

    }

}

 

 

 

好了,现在我们可以创建search.xhtml文件,用来显示搜索结果了。下面是该文件的一个片段。

 

<rich:dataGrid value="#{SearchManager.results}" var="garage">
    [ loop over the values ]
</rich:dataGrid>

 


然后,在pages.xml中添加一个到search.xhtml的入口。

 

 

 

 

还剩下一个步骤。我们需要添加一个搜索框到菜单里面。如果你使用了Seam的默认布局,你就会看见/view/layout文件夹下面有一个menu.xhtml文件。如果没有找到,只需要将下面这一段添加到你需要的地方

<h:form id="search_form">
    <h:inputText id="searchPattern" required="true" value="#{SearchManager.searchPattern}" />
    <h:commandButton action="/search.xhtml" value="search"></h:commandButton>
</h:form>

 

 


现在,你可以开始搜索你想要的对象了。是不是非常简单?但是,如果对象的一个属性是用来表示这个对象是否能显示在页面上,那应该怎么办?好的,在这种情况下,你需要添加一个过滤器。过滤器都继承自org.apache.lucene.search.Filter类。

想象一下,我们在产品类上有一个属性是用来标明产品的状态的,这个属性有三种值"L"表示有效的产品,"D"表示被删除的产品,"P"表示待发布的产品。显然,在用户搜索的时候,我们只想显示出可见的产品。所以我们需要添加一个过滤器:

 

public class LiveProductFilter extends Filter {
    private static final long serialVersionUID = 1l;
    public BitSet bits(IndexReader reader) throws IOException {
        BitSet bitSet = new BitSet( reader.maxDoc() );
        TermDocs termDocs = reader.termDocs( new Term("status", "L") );
        while ( termDocs.next() ) {
            bitSet.set( termDocs.doc() );
        }
         return bitSet;
        }
}

 

 

 

 

为了让Hibernate Search能够找到我们在产品类上添加的过滤器,我们需要添加下面这个注解:

 

@FullTextFilterDefs ( { @FullTextFilterDef(name="liveProduct", impl = LiveProductFilter.class, cache=false) })

 

 

好了,就写到这里。

分享到:
评论

相关推荐

    jboss seam

    Seam为持久化集成了JPA和Hibernate 3,为轻量化的异步性集成了EJB Timer Service和Quartz,为工作流集成了jBPM,为业务规则集成了JBoss规则,为电子邮件集成了Meldware Mail,为完整的文本搜索集成了Hibernate ...

    开源软件之道.part2of2

    7.3 jboss seam 89 7.4 equinox 91 7.5 hibernate 93 7.6 ibatis 95 7.7 lucene 97 7.8 webkit 99 第8章 开源软件之服务器软件 101 8.1 apache http服务器 101 8.2 tomcat 103 8.3 jetty 104 8.4 geronimo 105 8.5 ...

    java学习路线图

    - **Seam&Jboss**:理解Seam框架,熟悉Jboss应用服务器。 ### Java学习路径总结 Java学习之路漫长而充满挑战,但只要按照科学的学习路径,从基础开始,逐步深入,最终能够达到精通。从Java基础到Java API,再到...

    java学习路线

    - **Seam & JBoss**:学习Seam框架与JBoss服务器的集成。 **11. J2SE部分(重点)** - **JDBC编程(重点)**:回顾和深入理解JDBC,特别是在Java SE环境下的应用。 - **轻量级J2EE开发**:学习使用EJB3.0等技术...

    J2EE程序员需掌握的技术

    2. **持久层框架**:Hibernate、JDO、Ibatis等框架处理数据库操作,通过ORM(对象关系映射)减少手动编写SQL的负担。EJB3 Entity Bean则提供了更高级的企业级服务,如事务管理和安全性。 3. **应用程序框架**:...

    liferayPortal

    - Hibernate:一个面向对象的关系数据库管理工具。 - ICEfaces:一种Java服务器端的用户界面组件库。 - Java J2EE/JEE:一种广泛使用的Java企业级开发平台。 - jBPM:一个用于工作流和业务流程管理的引擎。 - ...

Global site tag (gtag.js) - Google Analytics