一、compass实现搜索
1、配置
1.1、加入如下jar包。
1.2、将compass与spring集成,让compass使用spring的事务,配置文件如下:
bean.xml文件中加入如下内容
<bean id="compass" class="org.compass.spring.LocalCompassBean"> <!-- 指定映射类方式 --> <property name="classMappings"> <list> <value>com.nbchina.bean.article.Article</value> <value>com.nbchina.bean.article.ArticleClass</value> </list> </property> <property name="compassSettings"> <props> <prop key="compass.engine.connection">file://e:/index</prop> <prop key="compass.engine.highlighter.default.formatter.simple.pre"><![CDATA[<font color='red'>]]></prop> <prop key="compass.engine.highlighter.default.formatter.simple.post"><![CDATA[</font>]]></prop> <prop key="compass.transaction.factory">org.compass.spring.transaction.SpringSyncTransactionFactory</prop> </props> </property> <property name="transactionManager" ref="transactionManager" /> </bean> <!-- CompassGps为CompassGpsDevice提供Compass对象,他们一起为程序提供索引的实时更新 --> <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"> <!-- 为gpsDevice属性注入针对JPA的GPS驱动 --> <bean class="org.compass.gps.device.jpa.JpaGpsDevice"> <property name="name" value="jpaDevice" /> <property name="entityManagerFactory" ref="entityManagerFactory" /> <property name="injectEntityLifecycleListener" value="true"/> </bean> </property> </bean> </list> </property> </bean>
@Entity @Searchable //通过这个注解,指明该类跟lucene中的document映射 public class Article { @Id @GeneratedValue(strategy=GenerationType.AUTO) @SearchableId private Integer id; @ManyToOne(cascade=CascadeType.REFRESH,optional=false) @JoinColumn(name="acid") @SearchableComponent private ArticleClass ac; //@SearchableComponent代表还要跟其他类关联 //boost=2数字越大级别越高,代表标题检索到的排序在前。默认为1. //index=Index.NO代表不参与索引 //store=Store.YES代表储存 //name="titleName" 有些字段和关联的其他表字段相同,那么可以重命名。 @Column(length=80,nullable=false) @SearchableProperty(boost=2,store=Store.YES, name="titleName") private String title; @Column(length=255) private String titleIntact; @Column(length=10) private String titleFontColor; @Column(length=255) private String linkURL; @Column(length=255) private String keyword; @Column(length=255) @SearchableProperty(index=Index.NO,store=Store.YES) private String intro; @Column(nullable=false) private Integer hits = 1; @Temporal(TemporalType.DATE) @Column(nullable=false) @SearchableProperty(index=Index.NO,store=Store.YES,format="yyyy-MM-dd") private Date updateTime = new Date(); @Column(nullable=false) private Boolean onTop = false; @Column(nullable=false) private Boolean elite = false; @Column(nullable=false) private Boolean hot = false; @Column(nullable=false) private Integer status = 0; @Column(nullable=false) private Integer deleted = 0; @Column(length=80) private String editor = "admin"; @Column(length=80) private String author = "佚名"; @Column(length=80) private String copyFrom; @Lob @Column(nullable=false) @SearchableProperty(store=Store.YES) private String content; @Column(nullable=true) private Integer includeImage = 0; @Lob private String uploadFiles; @Column(length=255) private String includeImageURL; @Column(length=255) private String voiceURL; }
@Entity @Searchable(root=false) public class ArticleClass implements Serializable{ //@Searchable(root=false)代表不是搜索的根类,是Article的配角,关联的类而已。 @Id @GeneratedValue(strategy=GenerationType.AUTO) @SearchableProperty(index=Index.NO, store=Store.YES) private Integer id; @Column(length=36,nullable=false) @SearchableProperty(index=Index.NO, store=Store.YES) private String name; @Column(length=200) private String note; @Column(nullable=false) private Boolean visible=true; @Column(nullable=false) private Integer orderId=0; @Column(length=255) private String imageURL; @Column(length=10) private String level; @OneToMany(cascade={CascadeType.REFRESH,CascadeType.REMOVE},mappedBy="parent") private Set<ArticleClass> childs = new HashSet<ArticleClass>(); @ManyToOne(cascade=CascadeType.REFRESH) @JoinColumn(name="parentid") private ArticleClass parent; @OneToMany(mappedBy="ac", cascade=CascadeType.REMOVE) @SearchableReference //表示引用article private Set<Article> articles = new HashSet<Article>(); }
建立ArticleSearchServiceBean.java
@Service @Transactional public class ArticleSearchServiceBean extends CompassDaoSupport implements ArticleSearchService { @Resource public void setSessionFactory(Compass compass){ super.setCompass(compass); } public QueryResult<Article> search(String key, int startIndex, int maxResult) { return this.getCompassTemplate().execute(new ArticleResultCallback(key, startIndex, maxResult)); } }
public class ArticleResultCallback implements CompassCallback<QueryResult<Article>> { private String key; private int startIndex; private int maxResult; public ProductResultCallback(String key, int startIndex, int maxResult) { this.key = key; this.startIndex = startIndex; this.maxResult = maxResult; } public QueryResult<Article> doInCompass(CompassSession session) throws CompassException { List<Article> articles = new ArrayList<Article>(); CompassHits hits = session.find(key); int lastIndex = startIndex + maxResult - 1; if(lastIndex>(hits.length()-1)) lastIndex = hits.length()-1; for(int i=startIndex; i<=lastIndex; i++){ Article article = (Article) hits.data(i); if(hits.highlighter(i).fragment("title")!=null){//处理高亮显示 article.setTitle(hits.highlighter(i).fragment("title")); } articles.add(article); } QueryResult<Article> qr = new QueryResult<Article>(); qr.setResultlist(articles); qr.setTotalrecord(hits.length());//设置查询到的总记录数 return qr; } }
QueryResult<Article> qr = articleSearchService.search("关键字", pageView.getFirstResult(), pageView.getMaxresult()); pageView.setQueryResult(qr);
public Order getLockOrder(String orderid, String employee){ em.createQuery("update Order o set o.employee=?1 where o.orderid=?2 and o.employee is null") .setParameter(1, employee).setParameter(2, orderid).executeUpdate(); em.flush(); return this.find(orderid); } public void unLock(String orderid){ em.createQuery("update Order o set o.employee=?1 where o.orderid=?2") .setParameter(1, null).setParameter(2, orderid).executeUpdate(); }
if(!order.getEmployee().equals(username)){ request.setAttribute("message", "该订单已被"+ order.getEmployee() + "锁定"); return mapping.findForward("message"); }
jsp内判断
<c:if test="${empty entry.employee || entry.employee==employee.username}"><a href="">载入订单</a></c:if> <c:if test="${!empty entry.employee && entry.employee!=employee.username}">被${entry.employee}锁定</c:if>
try{ Properties prop = new Properties(); prop.put("runtime.log", config.getServletContext().getRealPath("/WEB-INF/Log/velocity.log")); prop.put("file.resource.loader.path", config.getServletContext().getRealPath("/WEB-INF/VM")); prop.put("input.encoding", "UTF-8"); prop.put("output.encoding", "UTF-8"); Velocity.init(prop); System.out.println("Velocity Initialized"); }catch( Exception e ){ System.out.println("VSelocity error"); e.printStackTrace(); }
<html> <head> <title>测试</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> 尊敬的客户:${userName} </body> </html>使用代码如下
Template template = Velocity.getTemplate("mailContent.vm","UTF-8"); VelocityContext context = new VelocityContext(); context.put("userName", "测试名"); StringWriter writer = new StringWriter(); template.merge(context, writer); writer.flush(); String mailContent = writer.toString(); EmailSender.send(entry.getEmail(), "测试", mailContent, "text/html");
2、配置
第二步:把oscache安装目录下的/etc/oscache.properties 文件放入 /WEB-INF/classes目录.开发阶段,我们可以把该文件放置在src目录.
下载路径:http://www.opensymphony.com/oscache/
oscache.jar
\lib\commons-logging.jar
3、实例
使用OSCache作页面局部缓存
我们使用Oscache的标签<oscache></oscache>来进行页面的局部缓存.使用方法如下:
<%@taglib uri="http://www.opensymphony.com/oscache" prefix=“oscache"%>
<oscache:cache>
<%=new Date() %>
</oscache:cache>
缓存的key将以请求的URI+查询字串组成,如果你访问/oscache/index.jsp?name=ttt和/oscache/index.jsp?name=ppp将得到两份缓存。缓存默认存放在application范围,缓存时间默认为3600秒,即1小时.
<oscache:cache key=“name”>
name=${param.name}
</oscache:cache>
这时候缓存将以name为key,不再是请求的URI+查询字串组成,所以如果你访问/oscache/index.jsp?name=ttt和/oscache/index.jsp?name=ppp将得到一份缓存。
<oscache:cache key="name" scope="session">
name=${param.name}
</oscache:cache>
缓存范围设置为session,这时候缓存保存在用户的session中,如果用户的把浏览器关闭,再重新打开一个新浏览器,原来缓存的内容将不存在。
<oscache:cache key="name" time="10">
name=${param.name}
</oscache:cache>
上面设置了缓存的时间为10秒,超过10秒后,缓存的内容将失掉。
<oscache:cache key="name" time="60" refresh="${param.refresh}">
name=${param.name}
</oscache:cache>
refresh为true将会导致缓存的内容过期而被清除,简单地说,该属性为true用于清除缓存。
人为管理缓存<flush />标签:
<oscache:flush scope="application" />
清除application范围内的所有缓存
<oscache:flush scope="session" key="foobar" />
清除session范围内的key为foobar的缓存。
<oscache:flush scope="application" group="currencyData" />
清除application范围内组名为currencyData内的所有缓存。
在局部缓存,显示动态人名的时候。可以这么做。
你好<SCRIPT Languge=JavaScript src="welcome.js"></SCRIPT>,欢迎访问。
welcome.js代码如下。
function readCookieByName(name){ var nameOfCookie = name + "="; var x = 0; while ( x <= document.cookie.length ){ var y = (x+nameOfCookie.length); if ( document.cookie.substring( x, y ) == nameOfCookie ) { if ( (endOfCookie=document.cookie.indexOf( ";", y )) == -1 ) endOfCookie = document.cookie.length; return document.cookie.substring( y, endOfCookie ); } x = document.cookie.indexOf( " ", x ) + 1; if ( x == 0 ) break; } return ""; } function readWelcomeMsg(){ try{ var msg = readCookieByName("realName"); if(msg!=""){ return decodeURI(msg); }else{ msg = readCookieByName("userName"); if(msg!="") return msg; } } catch(e){ ; } return ""; } document.write(readWelcomeMsg());
页面全局缓存将使用Filter实现:
<filter> <filter-name>CacheFilter</filter-name> <filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class> <init-param> <param-name>time</param-name> <param-value>7200</param-value> </init-param> <init-param> <param-name>scope</param-name> <param-value>application</param-value> </init-param> </filter> <filter-mapping> <filter-name>CacheFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>
这个filter应该放在最上面,这样才会第一个通过它,如果存在缓存,就不需要访问后面,直接返回
缓存的key将以请求的URI+查询字串组成,如果你访问/oscache/index.jsp?name=ttt和/oscache/index.jsp?name=ppp将得到两份缓存。缓存是在初次访问页面时进行的,后续的请求将会返回缓存中的内容。缓存中存放的内容为页面返回给用户的html源代码。
oscache.properties文件设置如下:
3.1、include示范
<!--#fsize file="foot.html"-->将当前目录下news.html的文件大小入到当前页面
main.shtml内容
<html xmlns="http://www.w3.org/1999/xhtml"><HEAD> <TITLE>测试</TITLE> <META http-equiv="Content-Type" content="text/html; charset=UTF-8"> </HEAD> <BODY> <!--#include file="head.jsp" --> <br>中部<br> <!--#include file="foot.html" --> </BODY></html>
QUERY_STRING_UNESCAPED:显示未经转义处理的由客户端发送的查询字串,其中所有的特殊字符前面都有转义符"\"。
例如:<!--#echo var="QUERY_STRING_UNESCAPED" -->