Struts2+Hibernate3.2+Spring2.5+Compass整合

之前学习了Compass 现在整合下ssh2+Compass

网上找了很多资料 都没一个完整的demo 本人写的demo供大家分享 一步到位
希望可以让大家少走点弯路 如果ssh2都不会整合的 我就不多说了
[color=red]step1[/color]
在ssh2的基础上开发 加入jar包(compass-2.1.2.jar compass-index-patch.jar
lucene-analyzers-2.4.0.jar lucene-core-2.4.0.jar lucene-highlighter-2.4.0.jar paoding-analysis.jar

[color=red]step2[/color]
先来看下实体bean的编写
package com.v512.example.model;
import org.compass.annotations.*;
/**
* Product entity.
*
* @author MyEclipse Persistence Tools
*/
@Searchable
public class Product implements java.io.Serializable {

// Fields

@SearchableId
private String id;
@SearchableProperty(name="name",index=Index.ANALYZED,store=Store.YES)
private String name;
@SearchableProperty(name="price",index=Index.NOT_ANALYZED,store=Store.YES)
private Double price;
@SearchableProperty(name="brand",index=Index.ANALYZED,store=Store.YES)
private String brand;
@SearchableProperty(name="description",index=Index.ANALYZED,store=Store.YES)
private String description;

// Constructors

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

/** full constructor */
public Product(String name, Double price, String brand, String description) {
this.name = name;
this.price = price;
this.brand = brand;
this.description = description;
}

// Property accessors

public String getId() {
return this.id;
}

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

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Double getPrice() {
return this.price;
}

public void setPrice(Double price) {
this.price = price;
}

public String getBrand() {
return this.brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

public String getDescription() {
return this.description;
}

public void setDescription(String description) {
this.description = description;
}

}


[color=red]step3[/color]属性文件Product.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.v512.example.model.Product" table="PRODUCT" >
<id name="id" type="java.lang.String">
<column name="ID" length="40" />
<generator class="uuid.hex" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="80" />
</property>
<property name="price" type="java.lang.Double">
<column name="PRICE" precision="6" />
</property>
<property name="brand" type="java.lang.String">
<column name="BRAND" length="40" />
</property>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" length="2000" />
</property>
</class>
</hibernate-mapping>


要使用Compass必须加入一个applicationContext-compass.xml文件,文件名可以自行定义 这个就不用说了 废话

[color=red]step4[/color]applicationContext-compass.xml:
<?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"
default-lazy-init="true">

<!-- 配置compass的注解功能 -->
<bean id="annotationConfiguration"
class="org.compass.annotations.config.CompassAnnotationsConfiguration">
</bean>


<bean id="compass" class="org.compass.spring.LocalCompassBean">
<!-- 配置需要索引的实体映射文件的路径 -->
<property name="resourceDirectoryLocations">
<list>
<value>classpath:com/v512/example/model</value>
</list>
</property>
<!-- 设置存放索引的路径 -->
<property name="connection">
<value>/lucene/indexes</value>
</property>

<!--配置要搜索的类,作用:会根据以下的类建立索引 -->
<property name="classMappings">
<list>
<value>com.v512.example.model.Product</value>
</list>
</property>
<property name="compassConfiguration"
ref="annotationConfiguration" />

<!--compass的一些属性设置 -->
<property name="compassSettings">
<props>
<prop key="compass.transaction.factory">
org.compass.spring.transaction.SpringSyncTransactionFactory
</prop>
<prop key="compass.engine.analyzer.MMAnalyzer.CustomAnalyzer">net.paoding.analysis.analyzer.PaodingAnalyzer </prop>
</props>
</property>
<!--compass的事务管理器 -->
<property name="transactionManager" ref="transactionManager" />
</bean>


<bean id="hibernateGpsDevice"
class="org.compass.gps.device.hibernate.HibernateGpsDevice">
<property name="name">
<value>hibernateDevice</value>
</property>
<property name="sessionFactory" ref="sessionFactory" />
<property name="mirrorDataChanges">
<value>true</value>
</property>
</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>
<bean
class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">
<property name="gpsDevice" ref="hibernateGpsDevice" />
</bean>
</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.v512.example.service.impl.CompassIndexBuilder"
lazy-init="false">
<property name="compassGps" ref="compassGps" />
<property name="buildIndex" value="true" />
<property name="lazyTime" value="10" />
</bean>


</beans>


中间都有注解 就不多解释了

下面来编写dao及dao的实现以及severce层

[color=red]step5[/color]

package com.v512.example.dao;

import java.util.List;

import com.v512.example.model.Product;

public interface ProductDao {
public void create(Product p);
public Product getProduct(String id);
public List getProducts();
public void update(Product product);
public void remove(String id);

}


package com.v512.example.dao.hibernate;

import java.util.List;

import com.v512.example.dao.ProductDao;
import com.v512.example.model.Product;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class ProductDaoHibernate extends HibernateDaoSupport implements ProductDao {

public void create(Product p) {
getHibernateTemplate().save(p);

}

public Product getProduct(String id) {
return (Product)getHibernateTemplate().get(Product.class, id);
}

public List getProducts() {
return getHibernateTemplate().find("from Product order by id desc");
}

public void remove(String id) {
getHibernateTemplate().delete(getProduct(id));

}

public void update(Product product) {
getHibernateTemplate().saveOrUpdate(product);

}

}



servece

package com.v512.example.service;

import java.util.List;

import com.v512.example.model.Product;

public interface ProductManager {
public void insertProduct(Product p);
public Product findProdcut(String id);
public List searchProducts(String queryString);


}



servece的实现
package com.v512.example.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.compass.core.CompassHits;
import org.compass.core.CompassSession;
import org.compass.core.CompassTemplate;
import org.compass.core.CompassTransaction;

import com.v512.example.dao.ProductDao;
import com.v512.example.model.Product;
import com.v512.example.service.ProductManager;
import org.compass.core.Compass;
public class ProductManagerImpl implements ProductManager {
private ProductDao productDao;
private CompassTemplate compassTemplate;




public void setCompassTemplate(CompassTemplate compassTemplate){
this.compassTemplate=compassTemplate;
}

public void setProductDao(ProductDao productDao){
this.productDao=productDao;
}

public Product findProdcut(String id) {
return productDao.getProduct(id);
}

public void insertProduct(Product p) {
productDao.create(p);
}

public List searchProducts(String queryString) {
Compass compass = compassTemplate.getCompass();
CompassSession session=compass.openSession();
List list = new ArrayList();
//这里不需要开启事务了,因为在调用这个方法之前就已经开启了事务
CompassHits hits= session.queryBuilder().queryString("name:"+queryString).toQuery().hits();
System.out.println("queryString:"+queryString);
System.out.println("hits:"+hits.getLength());
for(int i=0;i<hits.length();i++){
Product hit=(Product)hits.data(i);
list.add(hit);
}

return list;
}


public CompassTemplate getCompassTemplate() {
return compassTemplate;
}

}


所有的都做完了
现在编写jsp页面

[color=red]step6[/color]
insertProduct.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="style/oa.css" rel="stylesheet" type="text/css">

<title>添加信息</title>
</head>
<body>
<center>
<s:form action="insert.action" theme="simple">

<TABLE class="tableEdit" border="0" cellspacing="1" cellpadding="0" style="width:300px;">
<TBODY>
<TR>
<td align="center" class="tdEditTitle">添加商品名称</TD>
</TR>
<TR>
<td>


<table class="tableEdit" style="width:300px;" cellspacing="0" border="0" cellpadding="0">
<tr>
<td class="tdEditLabel" >商品名称</td>
<td class="tdEditContent"><s:textfield name="product.name" label="名称" /></td>
</tr>

<tr>
<td class="tdEditLabel" >商品品牌</td>
<td class="tdEditContent"><s:textfield name="product.brand" label="品牌" /></td>
</tr>

<tr>
<td class="tdEditLabel" >商品价格</td>
<td class="tdEditContent"><s:textfield name="product.price" label="价格" /></td>
</tr>

<tr>
<td class="tdEditLabel" >商品描述</td>
<td class="tdEditContent"><s:textarea name="product.description" label="描述" />
</td>
</tr>
<tr>
<td> 
</td>
<td><s:submit/>
<br></td>
</tr>
</table>
</td>
</TR>
</TBODY>
</TABLE>
</s:form>
</center>
</body>
</html>

[color=red]step7[/color]

编写action
package com.v512.example.action;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;
import com.v512.example.model.Product;
import com.v512.example.service.ProductManager;
import org.apache.struts2.ServletActionContext;

public class ProductAction extends ActionSupport {

private static final long serialVersionUID = 3795048906805728732L;
private ProductManager productManager;
private Product product;
private String queryString;

public void setQueryString(String queryString){
this.queryString=queryString;
}

public Product getProduct() {
return product;
}

public void setProduct(Product product) {
this.product = product;
}

public void setProductManager(ProductManager productManager){
this.productManager=productManager;
}

public String insert(){
productManager.insertProduct(product);
return SUCCESS;
}
public String search(){
List results=productManager.searchProducts(queryString);
System.out.println(results.size());
ServletActionContext.getRequest().setAttribute("searchresults", results);
return SUCCESS;
}


}


[color=red]step8[/color]关于Struts2的配置文件如下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
<constant name="struts.objectFactory" value="spring" />

<include file="struts-default.xml"/>

<package name="product" extends="struts-default"
namespace="/product">

<!-- 配置Struts2的Action,class值要与applicationContext*.xml中的id的值一致。 -->
<action name="insert"
class="productBean" method="insert">
<result >insertOk.jsp</result>
</action>
<action name="search"
class="productBean" method="search">
<result >searchResults.jsp</result>
</action>

</package>

</struts>



如果插入成功就跳转到insertOk。jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
添加商品成功!

</body>
</html>


[color=red]step9[/color]到此所有准备工作都做完了
下面来看下 spring的配置文件applicationContext.xml 和web.xml
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!--定义Spring的配置的位置,可以定义多个配置文件,可以使用通配符。 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<!--设置一起动当前的Web应用,就加载Spring,让Spring管理Bean-->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!--解决Hibernate延迟加载出现的问题,需要放到struts2过滤器之前-->
<filter>
<filter-name>lazyLoadingFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>

<!--Struts2的过滤器,使用Struts2,必须配置该项-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>


<!--解决Hibernate延迟加载出现的问题,仍需要放到struts2过滤器mapping之前-->
<filter-mapping>
<filter-name>lazyLoadingFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<!--Struts2的过滤器,配套的filter-mapping-->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>


applicationContext.xml
<?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:aop="http://www.springframework.org/schema/aop"
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/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" default-lazy-init="true">




<!-- mysql数据库 :定义数据源的Bean ,给Hibernate的sessionFactory -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.gjt.mm.mysql.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssh2compass?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<!-- 连接池启动时的初始值 -->
<property name="initialSize" value="1"/>
<!-- 连接池的最大值 -->
<property name="maxActive" value="500"/>
<!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
<property name="maxIdle" value="2"/>
<!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
<property name="minIdle" value="1"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/v512/example/model/Product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=false
hibernate.format_sql=false
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=false
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
</value>
</property>
</bean>

<!-- oracle数据库 :定义数据源的Bean ,给Hibernate的sessionFactory-->
<!--
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="oracle.jdbc.driver.OracleDriver">
</property>
<property name="url"
value="jdbc:oracle:thin:@192.168.1.3:1521:ora9">
</property>
<property name="username" value="scott"></property>
<property name="password" value="tiger"></property>
</bean>
-->

<!-- 定义Hibernate的sessionFactory,通过该Bean,可以获得Hibernate的Session-->
<!--
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle9Dialect
</prop>
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>
com/v512/example/model/Product.hbm.xml
</value>
</list>
</property>
</bean>
-->

<bean id="productDao" class="com.v512.example.dao.hibernate.ProductDaoHibernate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="productManager" class="com.v512.example.service.impl.ProductManagerImpl">
<property name="productDao" ref="productDao"></property>
<property name="compassTemplate" ref="compassTemplate"></property>
</bean>

<bean id="productBean" class="com.v512.example.action.ProductAction" scope="prototype">
<property name="productManager" ref="productManager"></property>

</bean>


<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>

<!-- 配置事务特性 ,配置add、delete和update开始的方法,事务传播特性为required-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>

<!-- 配置那些类的方法进行事务管理,当前cn.com.jobedu.oa.service包中的子包、类中所有方法需要,还需要参考tx:advice的设置 -->
<aop:config>
<aop:pointcut id="allManagerMethod" expression="execution (* com.v512.example.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>

</beans>


到此已经可以测试了
测试完插入之后,所有准备工作都已完成 现在我们来测下搜索
search.jap

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:form action="search.action" method="post">
<s:textfield name="queryString" label="搜索产品"/>
<s:submit></s:submit>
</s:form>


</body>
</html>


搜索后的结果页面
searchResults.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="java.util.List"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%

if(((List)request.getAttribute("searchresults")).size()==0){
%>
no results found.
<%} %>

<table border="1">
<s:iterator value="#request.searchresults">
<tr><td>
<s:property value="name"/>
</td>
<td>

<s:property value="price"/></td>
<td>

<s:property value="brand"/></td>
<td>

<s:property value="description"/></td>
</tr>
</s:iterator>
</table>

</body>
</html>

[color=red]step10[/color]

另外得说下,该项目见索引的过程:服务器启动把需要建立索引的表的数据全部取出建立索引
在项目运行过程中,插入数据,容器检测到索引有变动,添加索引,这个可以自己测试

为此 要添加另外一个类:该类就是专门建索引用 注意包的位置

CompassIndexBuilder

package com.v512.example.service.impl;
import org.compass.gps.CompassGps;
import org.springframework.beans.factory.InitializingBean;


/**
* 通过quartz定时调度定时重建索引或自动随Spring ApplicationContext启动而重建索引的Builder.
* 会启动后延时数秒新开线程调用compassGps.index()函数.
* 默认会在Web应用每次启动时重建索引,可以设置buildIndex属性为false来禁止此功能.
* 也可以不用本Builder, 编写手动调用compassGps.index()的代码.
*
*/
public class CompassIndexBuilder implements InitializingBean {
// 是否需要建立索引,可被设置为false使本Builder失效.
private boolean buildIndex = false;

// 索引操作线程延时启动的时间,单位为秒
private int lazyTime = 10;

// Compass封装
private CompassGps compassGps;

// 索引线程
private Thread indexThread = new Thread() {

@Override
public void run() {
try {
Thread.sleep(lazyTime * 1000);
System.out.println("begin compass index...");
long beginTime = System.currentTimeMillis();
// 重建索引.
// 如果compass实体中定义的索引文件已存在,索引过程中会建立临时索引,
// 索引完成后再进行覆盖.
compassGps.index();
long costTime = System.currentTimeMillis() - beginTime;
System.out.println("compss index finished.");
System.out.println("costed " + costTime + " milliseconds");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};

/**
* 实现<code>InitializingBean</code>接口,在完成注入后调用启动索引线程.
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
if (buildIndex) {
//设置为后台线程
indexThread.setDaemon(true);
indexThread.setName("Compass Indexer");
indexThread.start();
}
}

public void setBuildIndex(boolean buildIndex) {
this.buildIndex = buildIndex;
}

public void setLazyTime(int lazyTime) {
this.lazyTime = lazyTime;
}

public void setCompassGps(CompassGps compassGps) {
this.compassGps = compassGps;
}
}


本项目中用的是paoding-analyzer
所以请在src目录下增加paoding-dic-home.properties文件

paoding.dic.home=C:/paoding/dic
paoding.dic.detector.interval=60

[color=green]
over[/color]
[color=darkblue]ok 到此结束 恭喜你 你已经可以轻松的给自己的项目加上索引功能了 [/color]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值