Hibernate Search(基于version3.4)--第一章Getting Start-程序员宅基地

技术标签: java  数据结构与算法  数据库  

 

Getting Start

 

1.1系统配置要求

java runtime JDK或JRE5以上版本
Hibernate Search hibernate-search-3.4.0.Final.jar及其所需依赖。可通过Jboss Maven仓库下载(http://repository.jboss.org/
nexus/content/groups/public-jboss/ )
Hibernate Core 3.4版本的Hibernate Search与3.6版本的Hibernate Core测试良好
JPA2 虽然Hinbernate Search没有用到JPA,但Hibernate的持久化必须要用到JPA(如@Entity等)

 

1.2通过Maven配置依赖

1.2.1添加Jboss Maven仓库

Xml代码 复制代码 收藏代码
  1. <settings>
  2. ...
  3. <profiles>
  4. ...
  5. <profile>
  6. <id>jboss-public-repository</id>
  7. <repositories>
  8. <repository>
  9. <id>jboss-public-repository-group</id>
  10. <name>JBoss Public Maven Repository Group</name>
  11. <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
  12. <layout>default</layout>
  13. <releases>
  14. <enabled>true</enabled>
  15. <updatePolicy>never</updatePolicy>
  16. </releases>
  17. <snapshots>
  18. <enabled>true</enabled>
  19. <updatePolicy>never</updatePolicy>
  20. </snapshots>
  21. </repository>
  22. </repositories>
  23. <pluginRepositories>
  24. <pluginRepository>
  25. <id>jboss-public-repository-group</id>
  26. <name>JBoss Public Maven Repository Group</name>
  27. <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
  28. <layout>default</layout>
  29. <releases>
  30. <enabled>true</enabled>
  31. <updatePolicy>never</updatePolicy>
  32. </releases>
  33. <snapshots>
  34. <enabled>true</enabled>
  35. <updatePolicy>never</updatePolicy>
  36. </snapshots>
  37. </pluginRepository>
  38. </pluginRepositories>
  39. </profile>
  40. </profiles>
  41. <activeProfiles>
  42. <activeProfile>jboss-public-repository</activeProfile>
  43. </activeProfiles>
  44. ...
  45. </setting>
<settings>
  ...
  <profiles>
    ...
    <profile>
      <id>jboss-public-repository</id>
      <repositories>
        <repository>
          <id>jboss-public-repository-group</id>
          <name>JBoss Public Maven Repository Group</name>
          <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
          <layout>default</layout>
          <releases>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
          </releases>
          <snapshots>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
          </snapshots>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>jboss-public-repository-group</id>
          <name>JBoss Public Maven Repository Group</name>
          <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
          <layout>default</layout>
          <releases>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
          </releases>
          <snapshots>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
          </snapshots>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>jboss-public-repository</activeProfile>
  </activeProfiles>
  ...
</setting>

 

 

1.2.2在Maven应用中添加依赖

Xml代码 复制代码 收藏代码
  1. <!--实际上只需要hibernate-search就足够了,因为maven会根据传递性依赖原则添加其他依赖,像hibnerate-core等等-->
  2. <dependency>
  3. <groupId>org.hibernate</groupId>
  4. <artifactId>hibernate-search</artifactId>
  5. <version>3.4.0.Final</version>
  6. </dependency>
  7. <!--当需要用到hibernate-entitymanager时添加-->
  8. <dependency>
  9. <groupId>org.hibernate</groupId>
  10. <artifactId>hibernate-entitymanager</artifactId>
  11. <version>3.6.3.Final</version>
  12. </dependency>
<!--实际上只需要hibernate-search就足够了,因为maven会根据传递性依赖原则添加其他依赖,像hibnerate-core等等-->
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-search</artifactId>
   <version>3.4.0.Final</version>
</dependency>
<!--当需要用到hibernate-entitymanager时添加-->
 <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
   <version>3.6.3.Final</version>
</dependency>

 

1.3hibernate.cfg.xml或persistence.xml配置

Xml代码 复制代码 收藏代码
  1. ...
  2. <property name="hibernate.search.default.directory_provider"
  3. value="filesystem"/>
  4. <property name="hibernate.search.default.indexBase"
  5. value="/var/lucene/indexes"/>
  6. ...
...
<property name="hibernate.search.default.directory_provider" 
          value="filesystem"/> 
<property name="hibernate.search.default.indexBase" 
          value="/var/lucene/indexes"/>
...

属性hibernate.search.default.directory_provider告诉hibernate使用哪个DirectoryProvider实现。在Apache Lucene中有一个概念Directory来保存Index Files。Hibernate通过DirectoryProvider来初始化和配置一个Lucene Directory实例。在本例中,我们使用一个能把Index Files保存在file system中的DirectoryProvider。当Index Files保存在file system中时,我们可以通过Luke工具实时查看Lucene索引文件。除了DirectoryProvider外,还需要告诉hibernate索引文件保存在哪个具体的目录中,这通过hibernate.search.default.indexBase属性来配置。

 

我们假设有两个由hibernate持久的类文件example.Book和example.Author,并且想要为该应用添加全文搜索能力。请看下面样例:

 

Java代码 复制代码 收藏代码
  1. package example;
  2. ...
  3. @Entity
  4. @Indexed
  5. public class Book {
  6. @Id
  7. @GeneratedValue
  8. private Integer id;
  9. @Field(index=Index.TOKENIZED, store=Store.NO)
  10. private String title;
  11. @Field(index=Index.TOKENIZED, store=Store.NO)
  12. private String subtitle;
  13. @IndexedEmbedded
  14. @ManyToMany
  15. private Set<Author> authors = new HashSet<Author>();
  16. @Field(index = Index.UN_TOKENIZED, store = Store.YES)
  17. @DateBridge(resolution = Resolution.DAY)
  18. private Date publicationDate;
  19. public Book() {
  20. }
  21. // standard getters/setters follow here
  22. ...
  23. }
package example;
...
@Entity
@Indexed
public class Book {
  @Id
  @GeneratedValue
  private Integer id;
  
  @Field(index=Index.TOKENIZED, store=Store.NO)
  private String title;
  
  @Field(index=Index.TOKENIZED, store=Store.NO)
  private String subtitle; 
  @IndexedEmbedded
  @ManyToMany 
  private Set<Author> authors = new HashSet<Author>();
  @Field(index = Index.UN_TOKENIZED, store = Store.YES)
  @DateBridge(resolution = Resolution.DAY)
  private Date publicationDate;
  
  public Book() {
  } 
  
  // standard getters/setters follow here
  ... 
}
Java代码 复制代码 收藏代码
  1. package example;
  2. ...
  3. @Entity
  4. public class Author {
  5. @Id
  6. @GeneratedValue
  7. private Integer id;
  8. @Field(index=Index.TOKENIZED, store=Store.NO)
  9. private String name;
  10. public Author() {
  11. }
  12. // standard getters/setters follow here
  13. ...
  14. }
package example;
...
@Entity
public class Author {
  @Id
  @GeneratedValue
  private Integer id;
  @Field(index=Index.TOKENIZED, store=Store.NO)
  private String name;
  public Author() {
  } 
 
  // standard getters/setters follow here
  ...
}

 

@Indexed:标注Book是可索引的。

@DocumentId:主键标注,当有@Id时可省略

@Field:标注哪些域是可搜索的。其中index=Index.TOKENIZED参数说明可以通过Analyzer解析,store=Store.NO参数说明是否在索引文件中保存该域的值。

Note:无论store=Store.NO还是store=Store.YES都不会影响最终的搜索能力。store.YES的作用是可以在搜索后可以直接从索引中获取域的完整值。在hibernate中,如果store=Store.NO,搜索结果中,域的值是通过数据库中获取,如果store=Store.YES,域的值是直接从索引文档中获取。

@DateBridge:因为Lucene只支持纯字符串的索引(Lucene2.9后支持数值索引),基于这样的原因,hibernate必须把Date类型的值转换成字符串

@IndexedEmbedded:该注解用于建立关联实体的索引。这是必须的,因为Lucene的索引文档是一种平整的数据结构,它不像数据库那样支持对象关联。为了确保author的名字可搜索,必须把author的名字作为Book索引文档的一个域。

 

1.4建立索引

Hibernate会在进行实体持久化,更新,删除操作时自动地建立索引。但是,你还必须为已经存在于数据库中的数据建立索引。下面的例子基于上面的配置和持久化类,展示了如何进行初始化索引。

Java代码 复制代码 收藏代码
  1. //使用Hibernate Session初始化索引
  2. FullTextSession fullTextSession = Search.getFullTextSession(session);
  3. fullTextSession.createIndexer().startAndWait();
//使用Hibernate Session初始化索引
FullTextSession fullTextSession = Search.getFullTextSession(session);
fullTextSession.createIndexer().startAndWait();
Java代码 复制代码 收藏代码
  1. //使用JPA初始化索引
  2. EntityManager em = entityManagerFactory.createEntityManager();
  3. FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
  4. fullTextEntityManager.createIndexer().startAndWait();
//使用JPA初始化索引
EntityManager em = entityManagerFactory.createEntityManager();
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
fullTextEntityManager.createIndexer().startAndWait();

运行了上面的代码后,你会在/var/lucene/indexes/中找到example.Book索引文件,你可能使用Luke查看索引文件,这可以帮助你更好地理解Hibernate Search。

 

1.5.建立搜索

有两种方法可以建立搜索,一种是直接使用Lucene的API,另一种是使用Hibernate Search query DSL。后者可以被包装成org.hibernate.Query,从而可以使用Hibernate API的机能。

 

通过Hibernate Session创建和运行搜索

Java代码 复制代码 收藏代码
  1. FullTextSession fullTextSession = Search.getFullTextSession(session);
  2. Transaction tx = fullTextSession.beginTransaction();
  3. // create native Lucene query unsing the query DSL
  4. // alternatively you can write the Lucene query using the Lucene query parser
  5. // or the Lucene programmatic API. The Hibernate Search DSL is recommended though
  6. QueryBuilder qb = fullTextSession.getSearchFactory()
  7. .buildQueryBuilder().forEntity( Book.class ).get();
  8. org.apache.lucene.search.Query query = qb
  9. .keyword()
  10. .onFields("title", "subtitle", "authors.name", "publicationDate")
  11. .matching("Java rocks!")
  12. .createQuery();
  13. // wrap Lucene query in a org.hibernate.Query
  14. org.hibernate.Query hibQuery =
  15. fullTextSession.createFullTextQuery(query, Book.class);
  16. // execute search
  17. List result = hibQuery.list();
  18. tx.commit();
  19. session.close();
FullTextSession fullTextSession = Search.getFullTextSession(session);
Transaction tx = fullTextSession.beginTransaction();
// create native Lucene query unsing the query DSL
// alternatively you can write the Lucene query using the Lucene query parser
// or the Lucene programmatic API. The Hibernate Search DSL is recommended though
QueryBuilder qb = fullTextSession.getSearchFactory()
    .buildQueryBuilder().forEntity( Book.class ).get();
org.apache.lucene.search.Query query = qb
  .keyword()
  .onFields("title", "subtitle", "authors.name", "publicationDate")
  .matching("Java rocks!")
 .createQuery();
// wrap Lucene query in a org.hibernate.Query
org.hibernate.Query hibQuery = 
    fullTextSession.createFullTextQuery(query, Book.class);
// execute search
List result = hibQuery.list();
  
tx.commit();
session.close();

通过JPA创建和运行搜索

Java代码 复制代码 收藏代码
  1. EntityManager em = entityManagerFactory.createEntityManager();
  2. FullTextEntityManager fullTextEntityManager =
  3. org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
  4. em.getTransaction().begin();
  5. // create native Lucene query unsing the query DSL
  6. // alternatively you can write the Lucene query using the Lucene query parser
  7. // or the Lucene programmatic API. The Hibernate Search DSL is recommended though
  8. QueryBuilder qb = fullTextSession.getSearchFactory()
  9. .buildQueryBuilder().forEntity( Book.class ).get();
  10. org.apache.lucene.search.Query query = qb
  11. .keyword()
  12. .onFields("title", "subtitle", "authors.name", "publicationDate")
  13. .matching("Java rocks!");
  14. .createQuery();
  15. // wrap Lucene query in a javax.persistence.Query
  16. javax.persistence.Query persistenceQuery =
  17. fullTextEntityManager.createFullTextQuery(query, Book.class);
  18. // execute search
  19. List result = persistenceQuery.getResultList();
  20. em.getTransaction().commit();
  21. em.close();
EntityManager em = entityManagerFactory.createEntityManager();
FullTextEntityManager fullTextEntityManager = 
    org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
em.getTransaction().begin();
// create native Lucene query unsing the query DSL
// alternatively you can write the Lucene query using the Lucene query parser
// or the Lucene programmatic API. The Hibernate Search DSL is recommended though
QueryBuilder qb = fullTextSession.getSearchFactory()
    .buildQueryBuilder().forEntity( Book.class ).get();
org.apache.lucene.search.Query query = qb
  .keyword()
  .onFields("title", "subtitle", "authors.name", "publicationDate")
  .matching("Java rocks!");
  .createQuery();
// wrap Lucene query in a javax.persistence.Query
javax.persistence.Query persistenceQuery = 
    fullTextEntityManager.createFullTextQuery(query, Book.class);
// execute search
List result = persistenceQuery.getResultList();
em.getTransaction().commit();
em.close(); 

1.6 Analyzer(解析器)

Analyzer指定了按怎么样的规则去分词,比如词干分析("refactor", "refactors", "refactored" and "refactoring"都会是被认为是同一个词),是否去掉一些stop words(a,an,the)等等。Hibernate提供了几种方式去配置analyzer。

  • 在配置文件中配置 hibernate.search.analyzer属性。这里配置的analyzer是默认的解析器。
  • 在类级别中添加注解@Analyzer
  • 在域级别添加注解@Analyzer

在@Analyzer注解可以指定完全限定名,也可以是一个由@AnalyzerDef定义的analyzer的引用名。后一种方式会利用Solr Analyzer Framework的工厂方法。你可以通过查看Solr JavaDoc 或查看Solr Wiki相关段落找到更多可用的工厂方法。

 

在下面的例子中,StandardTokenizerFactory首先经过两个过滤器工厂(filter factories)过滤:LowerCaseFilterFactory 和 SnowballPorterFilterFactory。StandardTokenizerFactory通过标点与‘-’来划分词语,但保留像email,internet地址的完整性。LowerCaseFilterFactory把字母统一变成小写,而SnowballPorterFilterFactory处理指定语言的词干分析。

 

一般地,使用Solr Framework需要先定义一个tokenizer,之后是任意数量的filter。

 

使用@AnalyzerDef和Solr Framework定义和使用Analyzer

Java代码 复制代码 收藏代码
  1. @Entity
  2. @Indexed
  3. @AnalyzerDef(name = "customanalyzer",
  4. tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
  5. filters = {
  6. @TokenFilterDef(factory = LowerCaseFilterFactory.class),
  7. @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = {
  8. @Parameter(name = "language", value = "English")
  9. })
  10. })
  11. public class Book {
  12. @Id
  13. @GeneratedValue
  14. @DocumentId
  15. private Integer id;
  16. @Field(index=Index.TOKENIZED, store=Store.NO)
  17. @Analyzer(definition = "customanalyzer")
  18. private String title;
  19. @Field(index=Index.TOKENIZED, store=Store.NO)
  20. @Analyzer(definition = "customanalyzer")
  21. private String subtitle;
  22. @IndexedEmbedded
  23. @ManyToMany
  24. private Set<Author> authors = new HashSet<Author>();
  25. @Field(index = Index.UN_TOKENIZED, store = Store.YES)
  26. @DateBridge(resolution = Resolution.DAY)
  27. private Date publicationDate;
  28. public Book() {
  29. }
  30. // standard getters/setters follow here
  31. ...
  32. }  

转载于:https://www.cnblogs.com/faylz/archive/2013/04/30/3051934.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/angyi5367/article/details/102427778

智能推荐

MAME打开ROM报错解决办法_mame bios and devices sets-程序员宅基地

文章浏览阅读6.1k次。MAME打开ROM红屏报错的解决办法_mame bios and devices sets

什么是CAP理论? cp ap原则的含义-程序员宅基地

文章浏览阅读1.2k次。什么是CAP理论?CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾CAP分别是什么?一致性(Consistency) (所有节点在同一时间具有相同的数据)可用性(Availability) (保证每个请求不管成功或者失败都有响应)分区容错性(Partition tolerance) (系统中任意信息的丢失或_cp ap

Linux Kernel 2.4.x / 2.6.x uselib() Local Privilege Escalation Exploit-程序员宅基地

文章浏览阅读195次。/** pwned.c - linux 2.4 and 2.6 sys_uselib local root exploit. PRIVATE.* it's not the best one, the ldt approach is definitively better.* discovered may 2004. no longer private beca..._linux 2.4 挖洞

C/C++ —— 十六进制类型字符串的转换_c++ 16进制转字符串-程序员宅基地

文章浏览阅读9.5k次,点赞2次,收藏4次。在实际工作中,字符串和其它数据类型的转换是很常见的,库函数有很多,比如 atoi , strtol , sscanf 等,这些函数网上有很多资料,我经常用到的就是十六进制的数值以字符串的形式传输,然后又要解析,这里记录一下我这边的做法:将2个字节的十六进制的字符串转成short int 2个字节的整形数据:_c++ 16进制转字符串

Kafka实战:从RDBMS到Hadoop,七步实现实时传输-程序员宅基地

文章浏览阅读4.8k次。对于那些想要把数据快速摄取到Hadoop中的企业来讲,Kafka是一个很好的选择。Kafka是什么?Kafka是一个分布式、可伸缩、可信赖的消息传递系统,利用发布-订阅模型来集成应用程序/数据流。同时,Kafka还是Hadoop技术堆栈中的关键组件,能够很好地支持实时数据分析或者货币化的物联网数据。

SharedPreferencesUtils_sharedpreferencesutils 爆红-程序员宅基地

文章浏览阅读216次。package com.goodfamily.gps.polling_and_maintenance.util;import java.util.Set;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import andr_sharedpreferencesutils 爆红

随便推点

spring开启注解的三种方式-程序员宅基地

文章浏览阅读1.2w次。本章使用c3p0做演示 方法一,编辑试事务开启事务核心类 DataSourceTransactionManager,不管是哪一种方式都需要创建该对象,该方式需要记住的类 TransactionTemplate, 其实很好记,使用spring操作数据库创建jdbcTemplate ,使用spring开启事务创建TransactionTemplatepublic class Transact_spring开启注解的三种方式

这份字节跳动历年校招Java面试真题解析,年薪50W_前端校招面试真题解析大全-程序员宅基地

文章浏览阅读174次。写在前面很多小伙伴留言说让我写一些工作过程中的真实案例,写些啥呢?想来想去,写一篇我在以前公司从零开始到用户超千万的数据库架构升级演变的过程吧。本文记录了我之前初到一家创业公司,从零开始到用户超千万,系统压力暴增的情况下是如何一步步优化MySQL数据库的,以及数据库架构升级的演变过程。升级的过程极具技术挑战性,也从中收获不少。希望能够为小伙伴们带来实质性的帮助。这些面试题你都会了吗?(精选97道Java核心面试题)常量池有哪些,数据结构,自己设计一个常量池String为啥设计为final,好_前端校招面试真题解析大全

mac系统下配置tomcat_tomcat苹果与windows有区别吗-程序员宅基地

文章浏览阅读380次。mac tomcat的安装_tomcat苹果与windows有区别吗

前端必会:CDN加速原理-程序员宅基地

文章浏览阅读137次。作者:Kandyhttps://www.jianshu.com/p/1dae6e1680ff一、什么是 CDNCDN的全称是(Content Delivery Network),即内..._前端面试 cdn加速原理,没有缓存到哪里拿

小习惯-程序员宅基地

文章浏览阅读334次。生活在熙熙攘攘中从未变得安静,有时候感觉自己就像一辆行走着的汽车,向往着速度,应和着节奏。

ABSTRACT SQL CONFIGURE 代码分析一_abstractsql sql.or()-程序员宅基地

文章浏览阅读500次。2021SC@SCSDU对于SQL的配置public abstract class AbstractSQLConfig implements SQLConfig { private static final String TAG = "AbstractSQLConfig"; public static String DEFAULT_DATABASE = DATABASE_MYSQL; public static String DEFAULT_SCHEMA = "sys";..._abstractsql sql.or()