hibernate Search 学习研究 附件是maven工程

 

Jboss 的 hibernate search 支持 hibernate 应该比较好。

 

所以想在项目 里面使用 hibernate search 进行 搜索。

 

分词使用的是 IKAnalyzer 

 

网站是 :

 

http://code.google.com/p/ik-analyzer/

 

使用的 是 hibernate 3.6.8 + spring 3.0.6 + hibernate search 3.4.1 +IKAnalyzer 3.2.8 

 

数据库是mysql  链接池是 c3p0 

 

 

在 hibernate search 3.4 版本的时候 就不需要配置 hibernate 的监听了。(Jboss 自家的东西支持就是好点)

 

下面是配置文件:

 

 

<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="packagesToScan">
			<list>
				<value>com.freewebsys</value>
			</list>
		</property>
		<!-- <property name="mappingDirectoryLocations"> <list> <value>classpath:com/**/pojo</value>
			</list> </property> -->
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
				<!-- <prop key="hibernate.dialect"> org.hibernate.dialect.Oracle9Dialect
					</prop> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect
					</prop> -->
				<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
				<prop key="cglib.use_reflection_optimizer">true</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
				<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
				<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
				<!-- <prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}
					</prop> -->
				<prop key="hibernate.query.substitutions">true 1, false 0, yes 'Y', no 'N'</prop>

				<!-- add hibernate search. -->
				<prop key="hibernate.search.default.directory_provider">${hibernate.search.default.directory_provider}</prop>
				<prop key="hibernate.search.default.indexBase">${hibernate.search.default.indexBase}</prop>
				<prop key="hibernate.search.analyzer">${hibernate.search.analyzer}</prop>

			</props>
		</property>
	</bean>

 

 

 

 

 

<property name="packagesToScan">这个属性直接可以把配置下面的java bena 读取出来。不用一条一条添加了。

 

 

然后就是配置 hiberante 事物。

 

 

<!-- ####下面是用spring对事务进行配置的代码.#####开始 -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
	</bean>

	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
		<property name="cacheQueries">
			<value>true</value>
		</property>
	</bean>

	<bean id="transactionInterceptor"
		class="org.springframework.transaction.interceptor.TransactionInterceptor">
		<property name="transactionManager" ref="transactionManager" />
		<property name="transactionAttributes">
			<props>
				<prop key="*">PROPAGATION_REQUIRED,-Exception</prop>
				<prop key="find*">PROPAGATION_REQUIRED,readOnly
				</prop>
				<prop key="list*">PROPAGATION_REQUIRED,readOnly
				</prop>
				<prop key="get*">PROPAGATION_REQUIRED,readOnly
				</prop><!-- find和get方法开头的是只读的事务,其他的都进行提交回滚. -->
			</props>
		</property>
	</bean>
	<bean
		class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="beanNames">
			<value>*Service</value>
			<!-- <value>*Mgr, *Service , *Director , *Outputter , importTask</value>
				这个是通过对事务进行批量配置.对bean的名字含有Service的统统进行事务配置. 这样严格控制业务逻辑在service实现.如果有在action层进行查询的无所谓.但是
				保持更新在action是绝度不行的. -->
		</property>
		<property name="interceptorNames">
			<list>
				<value>transactionInterceptor</value>
			</list>
		</property>
	</bean>

	<bean
		class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
		<property name="transactionInterceptor" ref="transactionInterceptor" />
	</bean>

	<!-- Auto scan the components -->
	<context:component-scan base-package="com.freewebsys" />

 

 

 

创建搜索的 bean 

 

 

package com.freewebsys.demo.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.hibernate.search.annotations.Analyzer;
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;
import org.wltea.analyzer.lucene.IKAnalyzer;

@Entity
@Table(name = "user_info")
@Indexed
public class UserInfo implements java.io.Serializable {

	private Long id;
	private String userName;
	private String passwd;
	private String city;
	private String content;

	public UserInfo() {
	}

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", unique = true, nullable = false)
	@DocumentId
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column(name = "user_name", unique = false, nullable = true, length = 100)
	@Field(name = "user_name", index = Index.TOKENIZED, store = Store.YES)
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	@Column(name = "passwd", unique = false, nullable = true, length = 100)
	@Field(name = "passwd", index = Index.TOKENIZED, store = Store.YES)
	public String getPasswd() {
		return passwd;
	}

	public void setPasswd(String passwd) {
		this.passwd = passwd;
	}

	@Column(name = "city", unique = false, nullable = true, length = 100)
	@Field(name = "city", index = Index.TOKENIZED, store = Store.YES)
	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	@Column(name = "content", unique = false, nullable = true, length = 4000)
	@Field(name = "content", index = Index.TOKENIZED, store = Store.YES, analyzer = @Analyzer(impl = IKAnalyzer.class))
	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	@Override
	public String toString() {
		return "UserInfo [id=" + id + ", userName=" + userName + ", passwd="
				+ passwd + ", city=" + city + ", content=" + content + "]";
	}

}

 

 

 

@Indexed 标识这个要被索引。

 

@Field(name = "user_name", index = Index.TOKENIZED, store = Store.YES)

标识 索引字段

 

 

@Field(name = "content", index = Index.TOKENIZED, store = Store.YES, analyzer = @Analyzer(impl = IKAnalyzer.class))

 

具体 其他参数 参考 博客 : http://sin90lzc.iteye.com/blog/1106258

 

标识索引字段并表示分词 为 IKAnalyzer

 

然后 就是 service 写的。。这里 省略了 dao 层 service 直接 继承 HibernateDaoSupport

 

 

package com.freewebsys.demo.service.impl;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.util.Version;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.freewebsys.demo.pojo.UserInfo;
import com.freewebsys.demo.service.UserInfoService;

@Service("userInfoService")
public class UserInfoServiceImpl extends HibernateDaoSupport implements
		UserInfoService {

	private static Log log = LogFactory.getLog(UserInfoServiceImpl.class);

	@Autowired
	public void setMySessionFactory(SessionFactory sessionFactory) {
		setSessionFactory(sessionFactory);
	}

	@Transactional
	public void save(UserInfo userInfo) {
		getHibernateTemplate().save(userInfo);
	}

	@Transactional
	public void delete(UserInfo userInfo) {
		getHibernateTemplate().delete(userInfo);
	}

	/**
	 * 使用hql 进行查询。
	 */
	@Transactional
	public List<UserInfo> findUserInfo(String userName) {
		String hql = " from UserInfo userInfo where userInfo.userName = ? ";
		return getHibernateTemplate().find(hql, userName);
	}

	public List<UserInfo> findUserInfoBySearchContent(String content) {
		FullTextSession fullTextSession = Search
				.getFullTextSession(getSession());

		QueryParser parser = new QueryParser(Version.LUCENE_31, "content",
				new SimpleAnalyzer(Version.LUCENE_31));
		org.apache.lucene.search.Query luceneQuery = null;
		try {
			luceneQuery = parser.parse(content);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(
				luceneQuery, UserInfo.class);
		List<UserInfo> useList = (List<UserInfo>) fullTextQuery.list();

		// 高亮设置
		SimpleHTMLFormatter formatter = new SimpleHTMLFormatter(
				"<b><font color='red'>", "</font></b>");

		QueryScorer qs = new QueryScorer(luceneQuery);
		Highlighter highlighter = new Highlighter(formatter, qs);
		// 这个20是指定关键字字符串的context的长度,你可以自己设定,因为不可能返回整篇正文内容
		highlighter.setTextFragmenter(new SimpleFragmenter(20));

		for (UserInfo userInfo : useList) {
			Analyzer analyzer = new IKAnalyzer();
			try {
				String contentHighLighter = highlighter.getBestFragment(
						analyzer, content, userInfo.getContent());
				System.out.println(contentHighLighter);
				userInfo.setContent(contentHighLighter);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return useList;

	}

	/**
	 * 查询全部数据
	 */
	public List<UserInfo> findAllUserInfo() {
		String hql = " from UserInfo userInfo";
		return getHibernateTemplate().find(hql);
	}

}

 最关键的就是搜索 然后 显示 高亮并 将文章内容截取 。

 

也可以使用setFirstResult setMaxResults 对搜索进行分页。

 

fullTextQuery.getResultSize() 是获得总页数。

 

 

					fullTextQuery.setFirstResult((pageNo - 1) * pageSize);
					fullTextQuery.setMaxResults(pageSize);

 

 

 

在使用 高亮显示的时候 二次进行了 分词。找到 查询内容:

 

 

// 高亮设置
		SimpleHTMLFormatter formatter = new SimpleHTMLFormatter(
				"<b><font color='red'>", "</font></b>");

		QueryScorer qs = new QueryScorer(luceneQuery);
		Highlighter highlighter = new Highlighter(formatter, qs);
		// 这个20是指定关键字字符串的context的长度,你可以自己设定,因为不可能返回整篇正文内容
		highlighter.setTextFragmenter(new SimpleFragmenter(20));

		for (UserInfo userInfo : useList) {
			Analyzer analyzer = new IKAnalyzer();
			try {
				String contentHighLighter = highlighter.getBestFragment(
						analyzer, content, userInfo.getContent());
				System.out.println(contentHighLighter);
				userInfo.setContent(contentHighLighter);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return useList;

 

在test 里面是测试 先初始化 数据库。

 

还可以对 数据里面的html 代码去掉。然后再展示:

 

QueryScorer qs = new QueryScorer(luceneQuery);
		Highlighter highlighter = new Highlighter(formatter, qs);
		// 这个20是指定关键字字符串的context的长度,你可以自己设定,因为不可能返回整篇正文内容
		highlighter.setTextFragmenter(new SimpleFragmenter(20));
		String contentStr = null;

		for (UserInfo userInfo : useList) {
			Analyzer analyzer = new IKAnalyzer();
			try {
				contentStr = userInfo.getContent();
				// 去掉所有html元素,
				contentStr = contentStr.replaceAll("<[a-zA-Z]+[1-9]?[^><]*>",
						"").replaceAll("</[a-zA-Z]+[1-9]?>", "");

				String contentHighLighter = highlighter.getBestFragment(
						analyzer, content, contentStr);
				System.out.println(contentHighLighter);
				userInfo.setContent(contentHighLighter);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

 

 

 

运行junit 测试:

 

 

List<UserInfo> list = userInfoService
				.findUserInfoBySearchContent("三个月");

		System.out.println(list.size());
		System.out.println("Finish ########");

		for (UserInfo userInfo : list) {
			System.out.println(userInfo);
		}

 

 

查询结果如下:

 

 

<b><font color='red'>三个月</font></b>必须到杭州进行全身心开发,<b><font color='red'>三个月</font></b>之后
<b><font color='red'>三个月</font></b>可以全身心在杭州专注于项目开发。<b><font color='red'>三个月</font></b>
开发的<b><font color='red'>三个月</font></b>内,天使湾将在杭州每周举办分享
<b><font color='red'>三个月</font></b>内,不同创业团队在确保独立自主的
地。在杭州<b><font color='red'>三个月</font></b>期间创业团队的住宿餐饮
<b><font color='red'>三个月</font></b>绝对以一当十! 9.天使湾聚变

 到页面就可以显示 高亮并 截取字符串了。

 

目前有一个问题就是 查询的时候 同时也执行 sql 查询。

 

如执行:

 

Hibernate: select this_.id as id0_0_, this_.city as city0_0_, this_.passwd as passwd0_0_, this_.user_name as user4_0_0_ from user_info this_ where (this_.id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?))

 

将 搜索查询 到的数据 从数据库中提取出来。

 

总的来说 hibernate search 将 搜索简化了很多。

 

附件是 工程代码:

 

 

时间: 2025-01-21 14:05:58

hibernate Search 学习研究 附件是maven工程的相关文章

hibernate Search 继续研究 增加 hibernate memcache 二级缓存 配置成功 附件maven代码(2)

首先安装 memecached 服务端:   之前写过的 文章,centos 安装memcached服务 :   http://toeo.iteye.com/blog/1240607   然后 在 前几天的 弄的  hibernate search 基础上,再添加 memcached 缓存.   因为 hibernate search 虽然 建立了索引.查询速度快了..但是依然要 load 数据.   证据就是 可以看到搜索如果有结果  肯定会执行 hql 将数据一次都查询出来.   Hiber

基于lucene搜索引擎的Hibernate Search,官方文档翻译

由于自己的项目需要用到搜索引擎,于是想到使用lucene,封装了lucene的框架有compass,solr,hibernate search. 网上对这些框架的描述有: Compass:是在Lucene的基础上做了封装,支持索引事务控制和增量索引,同时也能够和主流的SSH框架完美地整合在一起,操作Compass类似于操作Hibernate,它们的类/方法等设计的非常相似. 项目主页:http://www.compass-project.org/ 该项目已经很久没有更新维护了,官方网站显示最后维

Java EE7和Maven工程入门(1)

本文由 ImportNew - miracle1919 翻译自 javacodegeeks.欢迎加入翻译小组.转载请见文末要求. 目录 一个简单Maven工程的结构 为什么? 在日常工作中,我经常需要解决许多简单的或者是复杂的Maven/Java EE工程结构的问题.为了找到解决办法,我经常要拿项目的结构做实验,在不同应用服务器上对部署进行测试并且调优. 对新手来说,Maven可能有一个很漫长的学习曲线.如果你参与进一个经常需要非常复杂的配置的现代化的JavaEE应用的时候,事情会变得更糟.在我

1.Maven+SpringMVC+Eclipse软件安装配置,Maven报插件错误,Eclipse总是卡死的解决办法,导入一个maven工程后 一直显示importing maven project

 使用Maven+SpringMVC+Eclipse软件安装配置过程中的问题:   1.Eclipse总是卡死的解决办法: 一:内存不足所以会卡死,配置一下eclipse.ini修改这几个值就好了-XX:MaxPermSize=768m-Xms1024m-Xmx3072m搜索   二:修改window->preferences --- > JAVA->Edittor->Hovers,将右侧所有复选框清空.   2.因为eclipse上一次未正常关闭,导致启动卡死,错误日志为:

处女作就拿下 KDD 双料最佳论文runner-up,「半路出家」的他用深度学习研究气候问题(附讲解视频)

第一次投递论文,就中了 KDD,是什么样的体验? 第一次投 KDD,不仅中了,还同时获得了最佳论文 runner-up和最佳学生论文 runner-up,又是什么样的体验? 这两个知乎体问题,邀请东北大学 SDS(Sustainability & Data Science)实验室的博士生 Thomas Vandal 来回答最合适不过了.他的处女作<DeepSD: Generating High Resolution Climate Change Projections through Sin

【Maven由浅入深】3.在Eclipse中创建maven工程

紧接着上一篇,下面我们来学习如何在Eclispe(MyEclipse)中创建Maven工程. 如果我们使用的是光秃秃的eclipse(最原始的),那么我们要为eclipse下载一个插件,即是m2eclipse 我使用的是MyEclipse8.5版本,其中已经安装好了Maven插件. 打开我们的MyEclipse,我们点击Windows选项,然后选择Preferences选项,然后我们可以看到里面有一个Maven选项: 这是Myeclipse直接给我们的Maven,这个Maven我们是不能直接使用

Java EE7和Maven工程入门(2)

本文由 ImportNew - 陈 显鹭 翻译自 javacodegeeks.欢迎加入翻译小组.转载请见文末要求. 目录 一个简单Maven工程的结构 建立一个简单的WAR工程 先来回顾一下第一部分 我们已经建立了父pom文件.这种特殊类型的文件用来定义我们项目即将使用的类库,它也配置了所有为了打包项目的每个模块而使用的maven工具.你可以检出第一部分代码 . 所以,直到现在我们开发的项目目录中我们只有一个叫做sample-parent的文件夹.而且在这个目录中包括pom.xml文件--这就是

在eclipse中搭建maven工程(第二种方法)

第一种方法见前面的博客 用Maven创建web项目(详细步骤) maven-3.3.9 下载之后就是配置环境变量,可以去百度一哈,用MAVEN_HOME配置,我图方便,直接在用户的path配置的. 接下来我们修改我们本地的Maven仓库.默认本地仓库位置为:~.m2\repository,其中~表示当前用户的家目录,例如:C:\Users[你当前登录系统的用户名]. 我们现在自定义其位置:进入D:\java\maven-3.3.9\conf,打开settings.xml,在根标签settings

maven工程怎么使用自动生成的Mapper

问题描述 maven工程怎么使用自动生成的Mapper maven工程怎么使用自动生成的Mapper?需要配置什么东西么? 明明看得到那个文件可就是显示找不到 解决方案 POM中增加配置 <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> &l