lucene与hibernate 3.2.5集成配置
hibernate3.2以后,好像对lucene集成这一块多了一个项目hibernate-search,现有网上中文的配置,与这个有点出入。 现将我的配置过程记录如下: spring中配置: 在sessionFactory的配置中加上 <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/> <hibernate-configuration> 在domain的类前, @Indexed(Index/Products) 主键加上 @DocumentId 需要索引的字段前加@Field(index=Index.TOKENIZED, store=Store.NO) hibernate通过上面定义的listener,当要被索引的字段增删改的时候,会相应创建删除索引,有的时候,你可能不会真的删除数据库的数据,而是做了一个删除的标记,这个时候,需要重载一下定义的listener,注意,重载只有在3.0.1GA以上版本才行,因为这个版本的里面的一些方法的字段是private,在3.0.1.GA后是protected 或者自己实现PostUpdateEventListener, Initializable,接口,在配置的时候,写上自己的listener就行.
前几天看到Hibernate与Lucene的整合框架Hiberate Search3.0.0.GA版出来了,昨天试这写了一个Demo,感觉用起来的确很方便的,贴出来与大家分享一下。
java 代码
@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_" ) public Department getDept() { return dept; }
public void setDept(Department dept) { this .dept = dept; } }
java 代码
@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文件。
xml 代码
<? 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 >
xml 代码
<? 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属性指定索引保存的路径。
java 代码
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 ); } } |