不久前Hibernate推出了Hibernate Search 3.0
GA,由它的名字大家也可以大概猜到它的作用是對數據庫中的數據進行檢索的。它是hibernate對著名的全文檢索系統Lucene的一個集成方案,作
用在于對數據表中某些內容龐大的字段(如聲明為text的字段)建立全文索引,這樣通過hibernate
search就可以對這些字段進行全文檢索后獲得相應的POJO,從而加快了對內容龐大字段進行模糊搜索的速度(sql語句中like匹配)。
Hibernate Search運行的環境如下:
1、JDK或JRE 5.0以上
2、Hibernate-Search以及相應的依賴包
3、Hibernate Core 3.2.X
4、Hibernate Annotations 3.3.X
一、配置
使用過Lucene的人都知道,Lucene是使用Directory這個概念來存儲索引文件的,所以在Hibernate
Search中提供了一個初始化、配置化的工廠類DirectoryProvider來生成相應的Directory。而在這里,我使用了
FSDirectoryProvider這個工廠類,其中FS代表文件系統,意思是索引文件保存在文件系統中。因此,我們在hibernate.cfg.xml文件中加入了一下內容:
xml 代碼
-
<
property
?
name
=
"hibernate.search.default.directory_provider"
>
??
-
??????????org.hibernate.search.store.FSDirectoryProvider ??
-
</
property
>
??
-
<
property
?
name
=
"hibernate.search.default.indexBase"
>
??
-
??????????E:/temp/index ??
-
</
property
>
??
其中屬性hibernate.search.default.indexBase代表索引文件默認的保存位置。
這些屬性設置完成后,接下來就是使用Annotation對指定POJO的指定屬性進行配置了。如下:
java 代碼
-
@Indexed
(index?=?
"text"
) ??
-
public
?
class
?Text?
implements
?java.io.Serializable ??
-
{ ??
-
????
@DocumentId
??
-
????
private
?Integer?id; ??
-
??
-
????
private
?String?fileName; ??
-
??
-
????
private
?String?filePath; ??
-
??
-
????
@Field
(name?=?
"content"
,?store?=?Store.NO,?index?=?Index.TOKENIZED,?analyzer?=?
@Analyzer
(impl?=?ChineseAnalyzer.
class
)) ??
-
????
private
?String?content; ??
-
??
-
????...... ??
-
}??
其中@Indexed用于標示需要建立全文索引的實體類,它包含一個屬性index用于標示這個全文索引的名字
@DocumentId用于標示實體類中的唯一的屬性保存在索引文件中,是當進行全文檢索時可以這個唯一的屬性來區分索引中其他實體對象,一般使用實體類中的主鍵屬性
@Field就是用來標示Lucene的Field字段,其中name屬性用于標示Field的名稱,store屬性用于標示這個屬性的內容是否需要保存在索引中,index屬性標示該字段屬性是否進行分詞(Index.TOKENIZED),analyzer用于標示建立索引時所使用的分析器是什么類,這里使用Lucene自帶的ChineseAnalyzer
二、建立索引
配置完成以上設置之后,Hibernate Search的配置工作算是大功告成了,剩下的就是如何在編碼時使用到Hibernate
Search。其實Hibernate Search的使用與我們平時Hibernate的使用基本一致,索引的建立工作是可以由Hibernate
Search后臺自動處理的,無需手工操作,其中的主要差別有
1、Configuration
由于本文中Hibernate Search配置是由Annotation來完成的,所以我們在初始化Configuration、SessionFactory、Session時應該這樣寫:
java 代碼
-
factory?=?
new
?AnnotationConfiguration().configure(file).buildSessionFactory();??
使用AnnotationConfiguaration來代理平常使用的Configuration
2、Session
要使用Hibernate Search的功能就不能單純使用平常的Session來開始事務,進行數據庫操作,而是應該改用FullTextSession
java 代碼
-
??
-
Session?session?=?HibernateUtil.getSession(); ??
-
??
-
FullTextSession?fullTextSession?=?Search.createFullTextSession(session); ??
-
??
-
??
-
Transaction?tx?=?fullTextSession.beginTransaction(); ??
-
??
-
...... ??
-
??
-
??
-
tx.commit(); ??
-
??
-
fullTextSession.close();??
這樣,我們使用FullTextSession進行save,update,delete操作hibernate search將會自動根據配置在后臺對相應的域建立全文索引了
三、檢索
接下來就是說一下如何使用全文檢索功能來檢索實體對象了。
java 代碼
-
Session?session?=?HibernateUtil.getSession(); ??
-
FullTextSession?fullTextSession?=?Search.createFullTextSession(session); ??
-
??
-
Transaction?tx?=?fullTextSession.beginTransaction(); ??
-
??
-
QueryParser?parser?=?
new
?QueryParser(
"content"
,?
new
?ChineseAnalyzer()); ??
-
??
-
Query?query?=?fullTextSession.createFullTextQuery(parser.parse(word), ??
-
????????Text.
class
); ??
-
??
-
List?result?=?query.list(); ??
-
for
?(
int
?i?=?
0
;?result?!=?
null
?&&?i?<?result.size();?i++) ??
-
{ ??
-
????Text?pojo?=?(Text)?result.get(i); ??
-
????System.out.println(
"文件名:"
?+?pojo.getFileName()); ??
-
????System.out.println(
"文件路徑:"
?+?pojo.getFilePath()); ??
-
????System.out.println(); ??
-
} ??
-
??
-
tx.commit(); ??
-
fullTextSession.close();??
首先是建立相應的QueryParser由他來對輸入的關鍵字進行切分后產生Lucene下的Query實例,最后通過
FullTextSession的createFullTextQuery方法生成hibernate下的Query實例,執行list方法即可獲得查詢
的實例結果集合。
四、完