hibernate-search学习文档

1、 hibernate-search介绍

Hibernate Search是在apache Lucene的基础上建立的主要用于Hibernate的持久化模型的全文检索工具。像Lucene这样的检索引擎能够给我们的项目在进行检索的时候带来非常高的效率,但是它们在基本对象的检索时会有一些问题,比如不能实现检索内容跟实体的转换,Hibernate Search正是在这样的情况下发展起来的,基于对象的检索引擎,能够很方便的将检索出来的内容转换为具体的实体对象。此外Hibernate Search能够根据需要进行同步或异步的索引更新。

2、配置hibernate-search

2.1、spring+hibernate+jpa环境下增加如下依赖

 		核心
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-search</artifactId>
		</dependency>

		自带的分词器
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-search-analyzers</artifactId>
		</dependency>

		二级缓存,Infinispan作为二级缓存很好,不需要恢复,并且由于Cache的性质,您可以读取自己事务中的更改.
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-search-infinispan</artifactId>
		</dependency>
		
		IK分词器
		<dependency>
			<groupId>IKAnalyzer</groupId>
			<artifactId>IKAnalyzer</artifactId>
		</dependency>

		庖丁解牛分词器
		<dependency>
			<groupId>net.paoding.analysis.analyzer</groupId>
			<artifactId>paoding-analyzer</artifactId>
		</dependency>

2.2、 IK分词器配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 
	<entry key="ext_dict">ext.dic;</entry> 
	-->
	<!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords">stopword.dic;</entry> 
</properties>

2.3、 applicationContext.xml配置

在实体管理器中的jpaProperties下面添加

<prop key="hibernate.search.lucene_version" >LUCENE_36</prop>
<prop key="hibernate.search.default.directory_provider" >filesystem</prop>
<prop key="hibernate.search.default.indexBase" >target/lucene/indexes</prop>	
<!-- hibernate search Index Optimization -->
<prop key="hibernate.search.default.optimizer.operation_limit.max" >1000</prop>
<prop key="hibernate.search.default.optimizer.transaction_limit.max" >100</prop>

在applicationContext.xml中添加:

	<bean class=”org.hibernate.search.jpa.example.IndexManger” depends-on=”entityManagerFactory”/>
	<tx:advice id="txAdvice" transaction-manager="jpaTransactionManager">
		<tx:attributes>
			<tx:method name="save*" propagation="REQUIRED" />  
	        <tx:method name="add*" propagation="REQUIRED" />  
	        <tx:method name="create*" propagation="REQUIRED" />  
	        <tx:method name="insert*" propagation="REQUIRED" />  
	        <tx:method name="update*" propagation="REQUIRED" />  
	        <tx:method name="merge*" propagation="REQUIRED" />  
	        <tx:method name="del*" propagation="REQUIRED" />  
	        <tx:method name="remove*" propagation="REQUIRED" />  
	        <tx:method name="put*" propagation="REQUIRED" />  
	        <tx:method name="use*" propagation="REQUIRED" />  
	        <!--hibernate4必须配置为开启事务否则 getCurrentSession()获取不到-->  
	        <tx:method name="get*" propagation="REQUIRED" read-only="true" />  
	        <tx:method name="count*" propagation="REQUIRED" read-only="true" />  
	        <tx:method name="find*" propagation="REQUIRED" read-only="true" />  
	        <tx:method name="list*" propagation="REQUIRED" read-only="true" />  
	        <tx:method name="query*" propagation="REQUIRED" read-only="true" />  
	        <tx:method name="load*" propagation="REQUIRED" read-only="true" />  
	        <tx:method name="*" read-only="true" />  
		</tx:attributes>
	</tx:advice>
	<aop:config expose-proxy="true">
		<aop:pointcut expression="execution(* org.hibernate.search.jpa.example.service.*.*(..))" id="pointcut"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
	</aop:config

在hibernate的缓冲xml配置中添加:

<cache name="org.hibernate.search.jpa.example.model.Author" maxEntriesLocalHeap="1000" eternal="true"
		overflowToDisk="true" maxEntriesLocalDisk="10000" />
<cache name="org.hibernate.search.jpa.example.model.Book" maxEntriesLocalHeap="1000" eternal="true"
		overflowToDisk="true" maxEntriesLocalDisk="10000" />

庖丁分词器的配置

#values are "system-env" or "this";
#if value is "this" , using the paoding.dic.home as dicHome if configed!
#paoding.dic.home.config-fisrt=system-env
#dictionary home (directory)
#"classpath:xxx" means dictionary home is in classpath.
#e.g "classpath:dic" means dictionaries are in "classes/dic" directory or any other classpath directory
paoding.dic.home=classpath:dic
#seconds for dic modification detection
#paoding.dic.detector.interval=60

Stopword.dic 文件

a
an
and
are
as
at
be
but
by
for
if
in
into
is
it
no
not
of
on
or
such
that
the
their
then
there
these
they
this
to
was
will
With

2.4、 实体类的注解配置

2.4.1、 注解介绍

在类名上
加 @Indexed(index=””)的注解,用于jpa扫描,创建索引文件;

加@Analyzer(impl=PaodingAnalyzer.class or IKAnalyzer.class)标明使用的分词器

加@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="this.class")标明使用的注解

加@Boost(2.0f) 静态索引加速。与被索引实体的运行时状态无关。  
    1)可用在@Field的boost属性中、方法级、类级  
    2)不同方式指出的加速系数会累积,不能重复使用。如  
        @Field(boost=@Boost(1.5f))  
        @Boost(2f)  
        public String getSummary() { return summary;}  
      则summary系数为3,比普通域重要33)加速系数的指定并非精确的,可用来标注相对重要的实体或域。  
加@CacheFromIndex( { CLASS, ID } ) 对类和id进行缓存

在属性上面加
在id上面加@DocumentId 表示它索引的id,必须存储而且不能被分词,采用jpa时,可以不标明该注解

在属性上面加@Field,
name表示当前属性在luceneDocument中储存的名称,默认为变量名,
Store指定当前属性是否被存储在Luceneindex中,可选值为:
Store.YES,占用大量的索引空间,支持投影(projection),
Store.COMMPRESS压缩方式,消耗大量CPU,
Store.NO(deFault)
Index指定元素索引方式和信息存储类型,可选值为:
Index.NO 不索引,只有通过设置store才可以访问其内容;
Index.TOKENIZED(default),使用analyzer;
Index.UN_TOKENIZED,不使用analyzer;
Index.NO_NORMS,不存储正常化数据;
termVector检索词频  
TermVector.YES  
    	TermVector.NO(default)  
    	TermVector.WITH_OFFSETS  
    	TermVector.WITH_POSITIONS  
   	TermVector.WITH_POSITION_OFFSETS  
 indexNullAs  
 	Field.DO_NOT_INDEX_NULL  
     		 通过hibernate.search.default_null_token指定,默认为_null_  
     	 查询时使用相同的分词来查找空值,建议Index.UN_TOKENIZED时使用  
   	 Field.DEFAULT_NULL_TOKEN(default)  
boost 用法形如:boost=@Boost(2f),详见@Boost

@NumericField 
  	@Field的联合注解,用于Integer, Long,Float和Double属性,索引时采用字典树结构(Triestructure).  
  Lucene将此API标记为experimental,未来版本未必支持。HibernateSearch将尽量掩盖底层的API变化,但也未必能有效保证。  
 	 ->forField  
  	-> precisionStep(default4)  

@Fields 
 	同一个域采用不同的索引策略。需要为每个Field指定name属性(非强制).  
 当使用@Fields时,@Field将支持两个有用的属性:  
   	-> analyzer为每个field定义@Analyzer而非为属性定义  
   	-> bridge 每个field定义@FieldBridge而非为属性定义  

@IndexedEmbedded 
 对象有组合关系时使用。  
   	-> depth关联的深度,存在循环的依赖时使用。  
  	 -> prefix索引fields的前缀,默认为"属性名.",如address.city中的"address." 
  	 ->targetElement被标注的域不是实际对象类型(如声明类型为接口)时使用,用来指定实际对象类型  
 	 关联对象会自动被设为@Indexed 

@ContainedIn 
  	双相关联的对象中,另一方配合@IndexedEmbedded使用,保证Lucenedocument的联动更新。  
	 当前类被用JPA方式标注为@Embeddable时不需要使用@ContainedIn 

@Boost 
 静态索引加速。与被索引实体的运行时状态无关。  
    	1)可用在@Field的boost属性中、方法级、类级  
   	 2)不同方式指出的加速系数会累积,不能重复使用。如  
     	   @Field(boost=@Boost(1.5f))  
   	     @Boost(2f)  
  	      public String getSummary() { return summary;}  
      则summary系数为3,比普通域重要34)加速系数的指定并非精确的,可用来标注相对重要的实体或域。
  
@DynamicBoost 
 	动态索引加速。  

2.4.2. 实体类示例

在这里列举的两个实体类分别是book和author,省略去了getter/setter方法

book类:

@Entity
@Table(catalog="hibernate_search",name="Book")
@Indexed(index="book")
//@Analyzer(impl=IKAnalyzer.class)
@Analyzer(impl=PaodingAnalyzer.class)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="org.hibernate.search.hibernate.example.model.Book")  
@Boost(2.0f)
@CacheFromIndex( { CLASS, ID } )
public class Book {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;

	@Field(index = Index.YES, analyze = Analyze.YES, store = Store.COMPRESS)
	@Boost(1.5f)
	private String name;
	
	@Field(index = Index.YES, analyze = Analyze.YES, store = Store.COMPRESS)
	@Boost(1.2f)
	private String description;
	
	@Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)
	@DateBridge(resolution = Resolution.DAY)
	private Date publicationDate;

	@IndexedEmbedded(depth=1)
	@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH,CascadeType.REMOVE},fetch=FetchType.LAZY)
	@JoinTable(
			catalog="hibernate_search",
			name="Book_Author",
			joinColumns={@JoinColumn(name = "book_id")},
			inverseJoinColumns = {@JoinColumn(name = "author_id")}
	)
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="org.hibernate.search.hibernate.example.model.Author")
	private Set<Author> authors = new HashSet<Author>();

author类:

@Entity
@Table(catalog="hibernate_search",name="Author")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="org.hibernate.search.hibernate.example.model.Author")
public class Author {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	
	@Field(index=Index.YES,analyze=Analyze.NO,store=Store.COMPRESS)
	private String name;
	
	@ManyToMany(fetch=FetchType.LAZY,mappedBy="authors"/*,cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH,CascadeType.REMOVE}*/)
	@ContainedIn
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="org.hibernate.search.hibernate.example.model.Book")
	@JsonIgnore
	private Set<Book> books;

猜你喜欢

转载自blog.csdn.net/qq_42046342/article/details/105195391