Hibernate search实践
程序员文章站
2022-04-15 22:54:46
...
也许你的项目正在使用Spring+Hibernate,而你正好需要建立全文检索。Hibernate search可以无缝得整合Hibernate和Lucene,帮助你快速实现功能强大的全文检索。
Hibernate Search通过整合Hibernate core和Lucene建立持久化对象的索引。功能强大而配置简单。下载请到[url=http://hibernate.org/subprojects/search]官方网站[/url]。
Hibernate Search运行的环境如下:
1、JDK或JRE 5.0以上
2、Hibernate-Search以及相应的依赖包
3、Hibernate Core 3.2.X
4、Hibernate Annotations 3.3.X
首先将下载到的JAR包添加到你的项目中。
新建一个领域模型
接下来在类中加入Hibernate search注解
本文没有使用注解来完成类和数据的映射,而是使用book.hbm.xml的映射文件,当然你不用对映射文件做任何改动。如果你想使用注解,直接在类里中加入注解即可。
接下来需要修改hibernate.cfg.xml。在sessionFactory节中加入
到这里,配置和修改就已经完成了。当对象被插入,修改或删除的时候,将会出发索引的修改。
如果你想对数据库中已有的数据建立索引可以
这里每一千条会提交一次。如果出现内存溢出,可以把虚拟机的内存调大一些。
索引构建好了,就可以开始使用查询功能了。Hibernate search支持复杂检索 - 支持Wild Card(诸如*, ?等通配符号),多关键字,模糊查询,排序等。可以使用封装好的接口也可以调用底层的lucene接口(参考官方的手册)。
这里对title和summarize字段检索关键词"足球",并采取分页查询的策略。
重建索引也非常简单
Hibernate Search通过整合Hibernate core和Lucene建立持久化对象的索引。功能强大而配置简单。下载请到[url=http://hibernate.org/subprojects/search]官方网站[/url]。
Hibernate Search运行的环境如下:
1、JDK或JRE 5.0以上
2、Hibernate-Search以及相应的依赖包
3、Hibernate Core 3.2.X
4、Hibernate Annotations 3.3.X
首先将下载到的JAR包添加到你的项目中。
新建一个领域模型
public class Book {
Integer bookId;
String title;
String author;
String publishDate;
String summarize;
public Integer getBookId() {
return bookId;
}
public void setBookId(Integer bookId) {
this.bookId = bookId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPublishDate() {
return publishDate;
}
public void setPublishDate(String publishDate) {
this.publishDate = publishDate;
}
public String getSummarize() {
return summarize;
}
public void setSummarize(String summarize) {
this.summarize = summarize;
}
}
接下来在类中加入Hibernate search注解
//索引名称
@Indexed(index = "books")
//分词器
@Analyzer(impl = MMSegAnalyzer.class)
public class Book {
Integer bookId;
String title;
String author;
String publishDate;
String summarize;
//以对象的唯一标志做为索引中文档的唯一标志
@DocumentId
public Integer getBookId() {
return bookId;
}
public void setBookId(Integer bookId) {
this.bookId = bookId;
}
//索引title字段,并设置了权重
@Field(name = "title", index = Index.TOKENIZED, store = Store.YES, [email protected](2f))
@Boost(1.5f)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPublishDate() {
return publishDate;
}
public void setPublishDate(String publishDate) {
this.publishDate = publishDate;
}
//索引摘要字段,并设置权重
@Field(name = "summarize", index = Index.TOKENIZED, store = Store.YES, [email protected](1.2f))
public String getSummarize() {
return summarize;
}
public void setSummarize(String summarize) {
this.summarize = summarize;
}
}
本文没有使用注解来完成类和数据的映射,而是使用book.hbm.xml的映射文件,当然你不用对映射文件做任何改动。如果你想使用注解,直接在类里中加入注解即可。
接下来需要修改hibernate.cfg.xml。在sessionFactory节中加入
<property name="hibernate.search.default.directory_provider">
org.hibernate.search.store.FSDirectoryProvider
</property>
<property name="hibernate.search.default.indexBase">
D:\data\indexs
</property>
到这里,配置和修改就已经完成了。当对象被插入,修改或删除的时候,将会出发索引的修改。
如果你想对数据库中已有的数据建立索引可以
public class IndexBuilder {
static Logger log = Logger.getLogger("IndexBuilder");
public static void main(String[] args) {
Session session = null;
try {
//配置文件
ApplicationContext cxt = new FileSystemXmlApplicationContext(
"..\\WEB-INF\\applicationContext.xml");
SessionFactory sessionFactory = (SessionFactory) cxt
.getBean("sessionFactory");
session = sessionFactory.openSession();
FullTextSession fullTextSession = Search
.createFullTextSession(session);
Query query = session.createQuery("from Book")
.setMaxResults(1000);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
int j = 0;
int sum = 0;
log.info("start Indexing at "+df.format(Calendar.getInstance().getTimeInMillis()));
while (true) {
session.getTransaction().begin();
List<PvmsMaterialProgram> list = query.setFirstResult(j).list();
for (PvmsMaterialProgram program : list) {
fullTextSession.index(program);
}
session.getTransaction().commit();
j += 1000;
if (list.size() < 1000)
break;
sum += list.size();
log.info("finish " + sum + " records");
}
log.info("end at "+df.format(Calendar.getInstance().getTimeInMillis()));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null)
session.close();
}
}
}
这里每一千条会提交一次。如果出现内存溢出,可以把虚拟机的内存调大一些。
索引构建好了,就可以开始使用查询功能了。Hibernate search支持复杂检索 - 支持Wild Card(诸如*, ?等通配符号),多关键字,模糊查询,排序等。可以使用封装好的接口也可以调用底层的lucene接口(参考官方的手册)。
session = sessionFactory.getCurrentSession();
tx = session.beginTransaction();
String keyword = "足球"
FullTextSession fullTextSession = Search.createFullTextSession(session);
//这里同时对title和摘要字段进行检索
String[] fields = { "title", "summarize" };
String[] values = { keyword, keyword};
MultiFieldQueryParser parser = new MultiFieldQueryParser(
org.apache.lucene.util.Version.LUCENE_30, fields,new MMSegAnalyzer());
org.apache.lucene.search.Query luceneQuery = parser.parse(
org.apache.lucene.util.Version.LUCENE_30, values, fields,new MMSegAnalyzer());
//按发布时间排倒序
org.apache.lucene.search.Sort sort = new Sort(new SortField(
"publishDate", SortField.LONG, true));
FullTextQuery hibQuery = fullTextSession.createFullTextQuery(luceneQuery, Book.class);
//
hibQuery.setSort(sort);
//分页设置
hibQuery.setFirstResult(start);
hibQuery.setMaxResults(limit);
tx.commit();
// log.info("query list = "+hibQuery.list());
List books = hibQuery.list();
这里对title和summarize字段检索关键词"足球",并采取分页查询的策略。
重建索引也非常简单
FullTextSession fullTextSession = Search .getFullTextSession(sessionFactory.getCurrentSession());
//异步
fullTextSession.createIndexer().start();
//同步
//fullTextSession.createIndexer().startAndwait();
上一篇: 你搭公车去圣代早化了
下一篇: axios发送post form请求