前幾天看到Hibernate與Lucene的整合框架Hiberate Search3.0.0.GA版出來了,昨天試這寫了一個Demo,感覺用起來的確很方便的,貼出來與大家分享一下。
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;
/**
?*?Employee?generated?by?MyEclipse?Persistence?Tools
?
*/
@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
????
/**
?default?constructor?
*/
????
public
?Employee()?
{
????}
????
/**
?minimal?constructor?
*/
????
public
?Employee(Integer?empId)?
{
????????
this
.empId?
=
?empId;
????}
????
/**
?full?constructor?
*/
????
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;
/**
?*?Department?generated?by?MyEclipse?Persistence?Tools
?
*/
@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;
????}
????
/**
?default?constructor?
*/
????
public
?Department()?
{
????}
????
/**
?minimal?constructor?
*/
????
public
?Department(Integer?deptId)?
{
????????
this
.deptId?
=
?deptId;
????}
????
/**
?full?constructor?
*/
????
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
1、創建POJO







































































































































































































??? ??? 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、配置文件
























































3、測試代碼









































































































更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
