`
longgangbai
  • 浏览: 7248719 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring ,JPA,Compass使用注解开发的博客站内搜索

阅读更多

         当一个网站内部或个人博客搜索,设计思路:在发表博客和删除博客,修改博客是在保存的博客信息的同时,更新博客的索引 库,每一个用户一个特定的目录下一个特定的目录存储当前博主的索引信息,在搜索个人博客的信息或站内博客信息时使用.同时索引库必须在一定時間间隔内更新.保存索引库实时性.

  由于在项目中保存博客對象是同时建立相应的索引所以添加一层为装饰层Facade层,便于封装业务逻辑.

 

首先必须明白JPA,Spring注解注解的信息

JPA的配置:persistence.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="SpringJPASearchPU"
  transaction-type="RESOURCE_LOCAL">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <class>com.vnvtrip.search.jpa.blog.model.Blog</class>
  <properties>
   <property name="hibernate.connection.driver_class"
    value="com.mysql.jdbc.Driver" />
   <property name="hibernate.connection.url"
    value="jdbc:mysql://localhost:3306/search" />
   <property name="hibernate.connection.username" value="root" />
   <property name="hibernate.connection.password"
    value="123456" />
  </properties>
 </persistence-unit>

</persistence>

Spring的注解配置和JPA事物配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

 <!-- spring的注解配置 support annotation config -->
 <context:annotation-config />

 <context:component-scan
  base-package="com.vnvtrip.search.jpa.blog">
  <context:include-filter type="regex" expression=".model..*" />
  <context:include-filter type="regex" expression=".dao..*" />
  <context:include-filter type="regex" expression=".services..*" />
  <context:include-filter type="regex" expression=".facade..*" />
 </context:component-scan>
 <!--
  创建JPA事物管理器工厂
 -->
 <bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
  <property name="persistenceUnitName" value="SpringJPASearchPU" />
 </bean>
 <!--
  创建JPA事物管理器
 -->
 <bean id="txManager"
  class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory"
   ref="entityManagerFactory" />
 </bean>
 <!-- 注解事物的應用 -->
 <tx:annotation-driven transaction-manager="txManager" />
 
</beans>

 

Compass搜索配置如下:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
 xmlns:tx="http://www.springframework.org/schema/tx">
 <!--
  创建Compass注解配置對象
 -->
 <bean id="annotationConfiguration"
  class="org.compass.annotations.config.CompassAnnotationsConfiguration">
 </bean>

 <!-- 创建compass Bean创建本地搜索对象  -->
 <bean id="compass" class="org.compass.spring.LocalCompassBean">
  <!-- 解析的实体类的目录 -->
  <property name="resourceDirectoryLocations">
   <list>
    <value>classpath:com/vnvtrip/search/jpa/blog</value>
   </list>
  </property>
  <property name="classMappings">
   <list>
    <value>com.vnvtrip.search.jpa.blog.model.Blog</value>
   </list>
  </property>
  <property name="compassConfiguration"
   ref="annotationConfiguration" />
  <property name="transactionManager" ref="txManager" />
  <property name="compassSettings">
   <props>
    <!-- 配置高亮为红色 -->
    <prop
     key="compass.engine.highlighter.default.formatter.simple.pre">
     <![CDATA[ <font color="red"> <b>]]>
    </prop>
    <prop
     key="compass.engine.highlighter.default.formatter.simple.post">
     <![CDATA[ </b> </font>]]>
    </prop>
    <!-- 定义索引的存储位置  -->
    <prop key="compass.engine.connection">d:/compass</prop>
    <prop key="compass.transaction.factory">
     org.compass.spring.transaction.SpringSyncTransactionFactory
    </prop>
    <!-- 定义分词器-->
    <prop
     key="compass.engine.analyzer.MMAnalyzer.CustomAnalyzer">
     org.mira.lucene.analysis.IK_CAnalyzer
    </prop>
   </props>
  </property>

 </bean>
 <!--
  关于JPA的配置
 -->
 <bean id="jpaGpsDevice"
  class="org.compass.gps.device.jpa.JpaGpsDevice">
  <property name="name">
   <value>JpaGpsDevice</value>
  </property>
  <property name="entityManagerFactory"
   ref="entityManagerFactory" />
  <property name="mirrorDataChanges">
   <value>true</value>
  </property>
  <property name="injectEntityLifecycleListener" value="true"/>
 </bean>

 


 <!-- 数据库中的数据变化后同步更新索引 -->
 <bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps"
  init-method="start" destroy-method="stop">
  <property name="compass" ref="compass" />
  <property name="gpsDevices">
   <list>
         <ref bean="jpaGpsDevice"/>
   </list>
  </property>
 </bean>

 <!-- 检索使用的模板 -->
 <bean id="compassTemplate"
  class="org.compass.core.CompassTemplate">
  <property name="compass" ref="compass" />
 </bean>

 <!-- 定时重建索引(利用quartz)或随Spring ApplicationContext启动而重建索引 -->
 <bean id="compassIndexBuilder"
  class="com.vnvtrip.search.jpa.blog.utils.CompassIndexBuilder"
  lazy-init="false">
  <property name="compassGps" ref="compassGps" />
  <property name="buildIndex" value="true" />
  <property name="lazyTime" value="5" />
 </bean>
</beans>

Blog對象的实体类:

@Entity
@Table(name = "blog", catalog = "search")
@Searchable //用于注解实体类为检索实体类(必须的)
public class Blog implements java.io.Serializable {
 /**
  *
  */
 private static final long serialVersionUID = 1L;
 // Fields
 @Id
 @GeneratedValue(generator = "autoincrement", strategy = GenerationType.AUTO)
 @SearchableId  //用于注解实体的主键为检索索引的标识(必须的)
 private Integer blogid;
 private String author;
 private String subject;
 private String content;
 private String publishTime;

 // Constructors

 /** default constructor */
 public Blog() {
 }

 /** minimal constructor */
 public Blog(Integer blogid, String author) {
  this.blogid = blogid;
  this.author = author;
 }

 /** full constructor */
 public Blog(Integer blogid, String author, String subject, String content,
   String publishTime) {
  this.blogid = blogid;
  this.author = author;
  this.subject = subject;
  this.content = content;
  this.publishTime = publishTime;
 }

 // Property accessors
 @Id
 @Column(name = "blogid", nullable = false)
 public Integer getBlogid() {
  return this.blogid;
 }

 public void setBlogid(Integer blogid) {
  this.blogid = blogid;
 }

 @Column(name = "author", nullable = false, length = 25)
 public String getAuthor() {
  return this.author;
 }

 public void setAuthor(String author) {
  this.author = author;
 }

 @Column(name = "subject", length = 50)
 @SearchableProperty(index = Index.TOKENIZED, store = Store.YES)//設置检索的属性以及存储的方式
 public String getSubject() {
  return this.subject;
 }

 public void setSubject(String subject) {
  this.subject = subject;
 }

 @Column(name = "content", length = 500)
 @SearchableProperty(index = Index.TOKENIZED, store = Store.YES)
 public String getContent() {
  return this.content;
 }

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

 @Column(name = "publishTime", length = 25)
 public String getPublishTime() {
  return this.publishTime;
 }

 public void setPublishTime(String publishTime) {
  this.publishTime = publishTime;
 }

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((author == null) ? 0 : author.hashCode());
  result = prime * result + ((blogid == null) ? 0 : blogid.hashCode());
  result = prime * result + ((content == null) ? 0 : content.hashCode());
  result = prime * result
    + ((publishTime == null) ? 0 : publishTime.hashCode());
  result = prime * result + ((subject == null) ? 0 : subject.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  final Blog other = (Blog) obj;
  if (author == null) {
   if (other.author != null)
    return false;
  } else if (!author.equals(other.author))
   return false;
  if (blogid == null) {
   if (other.blogid != null)
    return false;
  } else if (!blogid.equals(other.blogid))
   return false;
  if (content == null) {
   if (other.content != null)
    return false;
  } else if (!content.equals(other.content))
   return false;
  if (publishTime == null) {
   if (other.publishTime != null)
    return false;
  } else if (!publishTime.equals(other.publishTime))
   return false;
  if (subject == null) {
   if (other.subject != null)
    return false;
  } else if (!subject.equals(other.subject))
   return false;
  return true;
 }

}

备注必须组件如下:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
 <classpathentry kind="src" path="src"/>
 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.springframework.MYECLIPSE_SPRING25_CORE"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.springframework.MYECLIPSE_SPRING25_AOP"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.springframework.MYECLIPSE_SPRING25_PERSISTENCE_CORE"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.springframework.MYECLIPSE_SPRING25_J2EE"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.springframework.MYECLIPSE_SPRING25_REMOTING"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.springframework.MYECLIPSE_SPRING25_WEB"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.springframework.MYECLIPSE_SPRING25_SUPPORT"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.springframework.MYECLIPSE_SPRING25_TESTING"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.springframework.MYECLIPSE_SPRING_JAVACONFIG_CORE"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.hibernate.MYECLIPSE_HIBERNATE3_2_EM"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.hibernate.MYECLIPSE_HIBERNATE3_2_CORE"/>
 <classpathentry kind="con" path="melibrary.com.genuitec.eclipse.hibernate.MYECLIPSE_HIBERNATE3_2_EXTRAS"/>
 <classpathentry kind="lib" path="lib/mysql-connector-java-3.2.0-alpha-bin.jar"/>
 <classpathentry kind="lib" path="lib/commons-dbcp.jar"/>
 <classpathentry kind="lib" path="lib/commons-logging.jar"/>
 <classpathentry kind="lib" path="lib/commons-pool.jar"/>
 <classpathentry kind="lib" path="lib/compass-2.2.0.jar"/>
 <classpathentry kind="lib" path="lib/IKAnalyzer.jar"/>
 <classpathentry kind="lib" path="lib/lucene-analyzers.jar"/>
 <classpathentry kind="lib" path="lib/lucene-core.jar"/>
 <classpathentry kind="lib" path="lib/lucene-highlighter.jar"/>
 <classpathentry kind="lib" path="lib/lucene-queries.jar"/>
 <classpathentry kind="lib" path="lib/lucene-snowball.jar"/>
 <classpathentry kind="lib" path="lib/lucene-spellchecker.jar"/>
 <classpathentry kind="lib" path="src/org.jar"/>
 <classpathentry kind="output" path="bin"/>
</classpath>

1
0
分享到:
评论
6 楼 longgangbai 2010-01-26  
integergx 写道
我不知道你测过没有,你的BlogTest里,搜索的是作者字段的内容,可你作者字段并没有设置进行索引。不知道你是故意的,还是忘了。



这个问题是应为我开始采用

public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml", "spring-search.xml" });
BlogFacade blogfacade = (BlogFacade) ctx.getBean("blogFacade");
Blog entity = new Blog();
entity.setBlogid(670);
entity.setAuthor(" my  money");
entity.setContent(" this is chinase content !");
entity.setSubject(" this is xiaobai  blog subject !");
entity.setPublishTime("2009-09-10");
///blogfacade.save(entity);
List<Blog> bloglist = blogfacade.find("content");
for (Blog blog : bloglist) {
System.out.println("blogId=" + blog.getBlogid() + " subject ="
+ blog.getSubject() + " context =" + blog.getContent());
}

红色部分是我以前测试的,后来无意改成“money”当然获取不到了!我测试compass注解是否跟我想象的一样的,很久了,今天在此说明!!
5 楼 longgangbai 2010-01-26  
integergx 写道
哥们,你是神啊,我一直建不起索引,原来是你给的mysql连接包出了问题,你怎么还用mysql3.x。哎,悲剧。



我以前用的版本,没有心的mysql驱动类库,请谅解!
4 楼 longgangbai 2010-01-26  
integergx 写道
我下载了,没法用啊,建立索引总是出异常,结果集为0,可数据库里已经有数据了



备注:我测试的环境中表结构必须存在!另外jar文件必须和我一样。我今天测试一下没有问题,怎么可能有问题!!
3 楼 integergx 2010-01-25  
我不知道你测过没有,你的BlogTest里,搜索的是作者字段的内容,可你作者字段并没有设置进行索引。不知道你是故意的,还是忘了。
2 楼 integergx 2010-01-25  
哥们,你是神啊,我一直建不起索引,原来是你给的mysql连接包出了问题,你怎么还用mysql3.x。哎,悲剧。
1 楼 integergx 2010-01-25  
我下载了,没法用啊,建立索引总是出异常,结果集为0,可数据库里已经有数据了

相关推荐

Global site tag (gtag.js) - Google Analytics