1、建立POJO

package com.yehui;


import javax.persistence.CascadeType;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.ManyToOne;

import javax.persistence.Table;


import org.hibernate.search.annotations.DocumentId;

import org.hibernate.search.annotations.Field;

import org.hibernate.search.annotations.Index;

import org.hibernate.search.annotations.Indexed;

import org.hibernate.search.annotations.IndexedEmbedded;

import org.hibernate.search.annotations.Store;


@Entity
@Table(name = " employee " , catalog = " hise " , uniqueConstraints = {} )

@Indexed(index = " indexes/employee " )
public class Employee implements java.io.Serializable {
private static final long serialVersionUID = 7794235365739814541L;
private Integer empId;
private String empName;
private Department dept;
private String empNo;
private Double empSalary;
// Constructors
public Employee() {
}
public Employee(Integer empId){
this.empId = empId;
}
public Employee(Integer empId, String empName,
String empNo, Double empSalary){
this.empId = empId;
this.empName = empName;
this.empNo = empNo;
this.empSalary = empSalary;
}
// Property accessors
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "emp_id", unique = true, nullable = false, insertable = true, updatable = true)
@DocumentId
public Integer getEmpId() {
return this.empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
@Column(name = "emp_name", unique = false, nullable = true, insertable = true, updatable = true, length = 30)
@Field(name="name", index=Index.TOKENIZED, store=Store.YES)
public String getEmpName() {
return this.empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
@Column(name = "emp_no", unique = false, nullable = true, insertable = true, updatable = true, length = 30)
@Field(index=Index.UN_TOKENIZED)
public String getEmpNo() {
return this.empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
@Column(name = "emp_salary", unique = false, nullable = true, insertable = true, updatable = true, precision = 7)
public Double getEmpSalary(){
return this.empSalary;
}
public void setEmpSalary(Double empSalary) {
this.empSalary = empSalary;
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="dept_id")
@IndexedEmbedded(prefix="dept_", depth=1)
public Department getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
}

package com.yehui;


import java.util.List;


import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.OneToMany;

import javax.persistence.Table;


import org.hibernate.search.annotations.ContainedIn;

import org.hibernate.search.annotations.DocumentId;

import org.hibernate.search.annotations.Field;

import org.hibernate.search.annotations.Index;

import org.hibernate.search.annotations.Indexed;

import org.hibernate.search.annotations.Store;


@Entity
@Table(name = " department " , catalog = " hise " , uniqueConstraints = {} )

@Indexed(index = " indexes/department " )
public class Department implements java.io.Serializable {
private static final long serialVersionUID = 7891065193118612907L;
private Integer deptId;
private String deptNo;
private String deptName;
private List<Employee> empList;
// Constructors
@OneToMany(mappedBy="dept")
@ContainedIn
public List<Employee> getEmpList() {
return empList;
}
public void setEmpList(List<Employee> empList) {
this.empList = empList;
}
public Department() {
}
public Department(Integer deptId) {
this.deptId = deptId;
}
public Department(Integer deptId, String deptNo, String deptName) {
this.deptId = deptId;
this.deptNo = deptNo;
this.deptName = deptName;
}
// Property accessors
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "dept_id", unique = true, nullable = false, insertable = true, updatable = true)
@DocumentId
public Integer getDeptId() {
return this.deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
@Column(name = "dept_no", unique = false, nullable = true, insertable = true, updatable = true, length = 30)
public String getDeptNo() {
return this.deptNo;
}
public void setDeptNo(String deptNo) {
this.deptNo = deptNo;
}
@Column(name = "dept_name", unique = false, nullable = true, insertable = true, updatable = true, length = 30)
@Field(name="name", index=Index.TOKENIZED,store=Store.YES)
public String getDeptName() {
return this.deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
} 不了解Hibernate映射相關的Annotation的朋友可以到Hibernate的官方網站下載下傳Hibernate Annotation Reference,有http://wiki.redsaga.com/翻譯的中文文檔。當然,也可以直接使用hbm.xml檔案。
Hibernate Search相關的Annotation主要有兩個:
@Indexed 辨別需要進行索引的對象,
屬性 index 指定索引檔案的路徑
@Field 标注在類的get屬性上,辨別一個索引的Field
屬性 index 指定是否索引,與Lucene相同
store 指定是否索引,與Lucene相同
name 指定Field的name,預設為類屬性的名稱
analyzer 指定分析器
另外@IndexedEmbedded 與 @ContainedIn 用于關聯類之間的索引
@IndexedEmbedded有兩個屬性,一個prefix指定關聯的字首,一個depth指定關聯的深度
如上面兩個類中Department類可以通過部門名稱name來索引部門,在Employee與部門關聯的字首為dept_,是以可以通過部門名稱dept_name來索引一個部門裡的所有員工。
2、配置檔案

<? xml version='1.0' encoding='UTF-8' ?>

<! DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >


< hibernate-configuration >


< session-factory >

< property name ="hibernate.dialect" >

org.hibernate.dialect.MySQLDialect

</ property >

< property name ="hibernate.connection.url" >

jdbc:mysql://localhost:3306/hise

</ property >

< property name ="hibernate.connection.username" > root </ property >

< property name ="hibernate.connection.password" > 123456 </ property >

< property name ="hibernate.connection.driver_class" >

com.mysql.jdbc.Driver

</ property >


< property name ="hibernate.search.default.directory_provider" >

org.hibernate.search.store.FSDirectoryProvider

</ property >

< property name ="hibernate.search.default.indexBase" > e:/index </ property >


< mapping class ="com.yehui.Employee" />

< mapping class ="com.yehui.Department" />

</ session-factory >


</ hibernate-configuration > 如果使用JPA,配置檔案為

<? xml version="1.0" encoding="UTF-8" ?>

< persistence xmlns ="http://java.sun.com/xml/ns/persistence"

xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation ="http://java.sun.com/xml/ns/persistence

http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version ="1.0" >


< persistence-unit name ="jpaPU" transaction-type ="RESOURCE_LOCAL" >

< provider > org.hibernate.ejb.HibernatePersistence </ provider >

< class > com.yehui.Department </ class >

< class > com.yehui.Employee </ class >

< properties >

< property name ="hibernate.connection.driver_class"

value ="com.mysql.jdbc.Driver" />

< property name ="hibernate.connection.url"

value ="jdbc:mysql://localhost:3306/hise" />

< property name ="hibernate.connection.username" value ="root" />

< property name ="hibernate.connection.password"

value ="123456" />

< property name ="hibernate.search.default.directory_provider"

value ="org.hibernate.search.store.FSDirectoryProvider" />

< property name ="hibernate.search.default.indexBase"

value ="e:/index" />

</ properties >

</ persistence-unit >


</ persistence > 主要就是添加兩個屬性, hibernate.search.default.directory_provider指定Directory的代理,即把索引的檔案儲存在硬碟中( org.hibernate.search.store.FSDirectoryProvider)還是記憶體裡( org.hibernate.search.store.RAMDirectoryProvider),儲存在硬碟的話 hibernate.search.default.indexBase屬性指定索引儲存的路徑。
3、測試代碼

package com.yehui;


import static junit.framework.Assert.assertNotNull;

import static junit.framework.Assert.assertTrue;


import java.util.List;


import org.apache.lucene.analysis.StopAnalyzer;

import org.apache.lucene.queryParser.QueryParser;

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.AnnotationConfiguration;

import org.hibernate.search.FullTextSession;

import org.hibernate.search.Search;

import org.junit.After;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

public class SearchResultsHibernate {
private static SessionFactory sf = null;
private static Session session = null;
private static Transaction tx = null;
@BeforeClass
public static void setupBeforeClass() throws Exception {
sf = new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();
assertNotNull(sf);
}
@Before
public void setUp() throws Exception {
session = sf.openSession();
tx = session.beginTransaction();
tx.begin();
}
@After
public void tearDown() throws Exception {
tx.commit();
session.close();
}
public static void tearDownAfterClass() throws Exception {
if (sf != null)
sf.close();
}
@Test
public void testAddDept() throws Exception {
Department dept = new Department();
dept.setDeptName("Market");
dept.setDeptNo("6000");
Employee emp = new Employee();
emp.setDept(dept);
emp.setEmpName("Kevin");
emp.setEmpNo("KGP1213");
emp.setEmpSalary(8000d);
session.save(emp);
}
@Test
public void testFindAll() throws Exception {
Query query = session.createQuery("from Department");
List<Department> deptList = query.list();
assertTrue(deptList.size() > 0);
}
@Test
public void testIndex() throws Exception {
FullTextSession fullTextSession = Search.createFullTextSession(session);
assertNotNull(session);
QueryParser parser = new QueryParser("name", new StopAnalyzer());
org.apache.lucene.search.Query luceneQuery = parser
.parse("name:Kevin");
Query hibQuery = fullTextSession.createFullTextQuery(luceneQuery,
Employee.class);
List list = hibQuery.list();
assertTrue(list.size() > 0);
}
@Test
public void testIndex2() throws Exception {
FullTextSession fullTextSession = Search.createFullTextSession(session);
assertNotNull(session);
QueryParser parser = new QueryParser("dept_name", new StopAnalyzer());
org.apache.lucene.search.Query luceneQuery = parser
.parse("dept_name:Market");
Query hibQuery = fullTextSession.createFullTextQuery(luceneQuery,
Employee.class);
List list = hibQuery.list();
assertTrue(list.size() > 0);
}
}
測試通過。OK
原文:http://blog.csdn.net/yanghuw/archive/2007/09/30/1808011.aspx
-------------------------------------------------------------------------------------------------------------------------------------
不久前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 session = HibernateUtil.getSession();
- //封裝Session為FullTextSession
- 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方法即可獲得查詢的執行個體結果集合。
四、完
以上便是今天我對Hibernate Search的一個嘗試,屬于很基礎很基礎的入門,希望可以對大家能有一些啟發跟幫助,随文附帶我的源代碼
- src.zip (5.8 KB)
- 描述: 源代碼與配置檔案