一) 创建LuceneUtil工具类,使用反射,封装通用的方法
/**
* 工具类
* @author Administrator
*
*/
public class LuceneUtil {
private static Directory directory;
private static Version version;
private static Analyzer analyzer;
private static MaxFieldLength maxFieldLength;
static{
try {
directory=FSDirectory.open(new File("E:/IndexDB"));
version=Version.LUCENE_30;
analyzer=new StandardAnalyzer(version);
maxFieldLength=MaxFieldLength.LIMITED;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//防止外界new该帮助类
private LuceneUtil(){}
//将javabean转成Docuement对象
public static Document javabenaToDocuemnt(Object obj)throws Exception{
Document document=new Document();
//获取obj的对象字节码
Class clazz = obj.getClass();
//通过对象字节码获取私有的属性
java.lang.reflect.Field[] reflectFields = clazz.getDeclaredFields();
for(java.lang.reflect.Field reField:reflectFields){
//强力反射
reField.setAccessible(true);
//获取属性名,id/title/content
String name = reField.getName();
String methodName="get"+name.substring(0, 1).toUpperCase()+name.substring(1);
//获取方法,例如:getId()/getTitle()
Method method=clazz.getMethod(methodName, null);
String value = method.invoke(obj, null).toString();
//加入到Docuemnt对象中去,这时javabean的属性与document对象的属性相同
document.add(new org.apache.lucene.document.Field(name, value, Store.YES, Index.ANALYZED));
}
return document;
}
//将Docuemnt对象转成javabean对象
public static Object docuemntToJavaBean(Document document,Class clazz)throws Exception{
Object obj=clazz.newInstance();
java.lang.reflect.Field[] reflectFields = clazz.getDeclaredFields();
for(java.lang.reflect.Field reField:reflectFields){
reField.setAccessible(true);
String name = reField.getName();
String value = document.get(name);
BeanUtils.setProperty(obj, name, value);
}
return obj;
}
public static Directory getDirectory() {
return directory;
}
public static void setDirectory(Directory directory) {
LuceneUtil.directory = directory;
}
public static Version getVersion() {
return version;
}
public static void setVersion(Version version) {
LuceneUtil.version = version;
}
public static Analyzer getAnalyzer() {
return analyzer;
}
public static void setAnalyzer(Analyzer analyzer) {
LuceneUtil.analyzer = analyzer;
}
public static MaxFieldLength getMaxFieldLength() {
return maxFieldLength;
}
public static void setMaxFieldLength(MaxFieldLength maxFieldLength) {
LuceneUtil.maxFieldLength = maxFieldLength;
}
}
二) 使用LuceneUtil工具类,完成CURD操作
public class ArticleDao {
@Test
public void add()throws Exception{
Article article=new Article(1,"培训","武汉有很多家培训机构");
Document docuemnt = LuceneUtil.javabenaToDocuemnt(article);
IndexWriter indexWriter=new IndexWriter(LuceneUtil.getDirectory(),LuceneUtil.getAnalyzer(), LuceneUtil.getMaxFieldLength());
indexWriter.addDocument(docuemnt);
indexWriter.close();
}
@Test
public void addAll()throws Exception{
IndexWriter indexWriter=new IndexWriter(LuceneUtil.getDirectory(),LuceneUtil.getAnalyzer(),LuceneUtil.getMaxFieldLength());
Article article1=new Article(1,"培训","武汉有很多家java培训机构");
Document docuemnt1 = LuceneUtil.javabenaToDocuemnt(article1);
indexWriter.addDocument(docuemnt1);
Article article2=new Article(2,"培训","武汉有很多家net培训机构");
Document docuemnt2 = LuceneUtil.javabenaToDocuemnt(article2);
indexWriter.addDocument(docuemnt2);
Article article3=new Article(3,"培训","武汉有很多家php培训机构");
Document docuemnt3 = LuceneUtil.javabenaToDocuemnt(article3);
indexWriter.addDocument(docuemnt3);
Article article4=new Article(4,"培训","武汉有很多家ios培训机构");
Document docuemnt4 = LuceneUtil.javabenaToDocuemnt(article4);
indexWriter.addDocument(docuemnt4);
Article article5=new Article(5,"培训","武汉有很多家ios培训机构");
Document docuemnt5 = LuceneUtil.javabenaToDocuemnt(article5);
indexWriter.addDocument(docuemnt5);
Article article6=new Article(6,"培训","武汉有很多家ios培训机构");
Document docuemnt6 = LuceneUtil.javabenaToDocuemnt(article6);
indexWriter.addDocument(docuemnt6);
Article article7=new Article(7,"培训","武汉有很多家ios培训机构");
Document docuemnt7 = LuceneUtil.javabenaToDocuemnt(article7);
indexWriter.addDocument(docuemnt7);
indexWriter.close();
}
@Test
public void update()throws Exception{
Article article=new Article(4,"培训","武汉有很多家IOS培训机构");
Document docuemnt = LuceneUtil.javabenaToDocuemnt(article);
IndexWriter indexWriter=new IndexWriter(LuceneUtil.getDirectory(),LuceneUtil.getAnalyzer(),LuceneUtil.getMaxFieldLength());
//更新id为4的docuemnt对象
/**
* 参数一:term表示需要更新的document对象
* id表示document对象中的id属性
* 7表示该id属性的值
* 参数二:新的docuemnt对象
*/
indexWriter.updateDocument(new Term("id","4"),docuemnt);
indexWriter.close();
}
@Test
public void delete()throws Exception{
IndexWriter indexWriter=new IndexWriter(LuceneUtil.getDirectory(),LuceneUtil.getAnalyzer(),LuceneUtil.getMaxFieldLength());
indexWriter.deleteDocuments(new Term("id","4"));
indexWriter.close();
}
@Test
public void deleteAll()throws Exception{
IndexWriter indexWriter=new IndexWriter(LuceneUtil.getDirectory(),LuceneUtil.getAnalyzer(),LuceneUtil.getMaxFieldLength());
indexWriter.deleteAll();
indexWriter.close();
}
@Test
public void searchByKey()throws Exception{
String keywords="培";
List<Article> articles=new ArrayList<Article>();
QueryParser queryParser=new QueryParser(LuceneUtil.getVersion(),"content",LuceneUtil.getAnalyzer());
Query query = queryParser.parse(keywords);
IndexSearcher indexSearcher=new IndexSearcher(LuceneUtil.getDirectory());
TopDocs topDocs=indexSearcher.search(query, 100);
for(int i=0;i<topDocs.scoreDocs.length;i++){
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
int no = scoreDoc.doc;
Document document = indexSearcher.doc(no);
Article article =(Article) LuceneUtil.docuemntToJavaBean(document, Article.class);
articles.add(article);
}
for(Article article:articles){
System.out.println(article);
}
}
}
三)使用lucene完成简单的分页查询
实体类:
public class Article {
private Integer id;//标题
private String title;//标题
private String content;//内容
public Article(){}
public Article(Integer id, String title, String content) {
this.id = id;
this.title = title;
this.content = content;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "编号:"+id+"\n标题:"+title+"\n内容:"+content;
}
}
Page包装类:
public class Page {
private Integer currPageNo;//当前页
private Integer perPageSize=3;//每页显示记录数,默认为2
private Integer allRecordNo;//总记录数
private Integer allPageNo;//总页数
private List<Article> articles=new ArrayList<Article>();
public Page(){}
public Integer getCurrPageNo() {
return currPageNo;
}
public void setCurrPageNo(Integer currPageNo) {
this.currPageNo = currPageNo;
}
public Integer getPerPageSize() {
return perPageSize;
}
public void setPerPageSize(Integer perPageSize) {
this.perPageSize = perPageSize;
}
public Integer getAllRecordNo() {
return allRecordNo;
}
public void setAllRecordNo(Integer allRecordNo) {
this.allRecordNo = allRecordNo;
}
public Integer getAllPageNo() {
return allPageNo;
}
public void setAllPageNo(Integer allPageNo) {
this.allPageNo = allPageNo;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
}
dao类:
/**
* 持久层
* @author Administrator
*
*/
public class ArticleDao {
/**
* 根据关键字,获取总记录数
* @param keywords
* @return
* @throws Exception
*/
public int getAllRecord(String keywords)throws Exception{
QueryParser queryParser=new QueryParser(LuceneUtil.getVersion(),"content",LuceneUtil.getAnalyzer());
Query query = queryParser.parse(keywords);
IndexSearcher indexSearcher=new IndexSearcher(LuceneUtil.getDirectory());
TopDocs topDocs=indexSearcher.search(query, 2);
//返回符合条件的真实总记录数,受2的影响
// return topDocs.scoreDocs.length;
//返回符合条件的真实总记录数,不受2的影响
return topDocs.totalHits;
}
/**
* 根据关键字,批量查询
* @param keywords
* @param start从第几条开始查询,索引号从0开始
* @param size最多查多少条
* @return
* @throws Exception
*/
public List<Article> findAll(String keywords,int start,int size)throws Exception{
List<Article> articles=new ArrayList<Article>();
QueryParser queryParser=new QueryParser(LuceneUtil.getVersion(),"content",LuceneUtil.getAnalyzer());
Query query = queryParser.parse(keywords);
IndexSearcher indexSearcher=new IndexSearcher(LuceneUtil.getDirectory());
TopDocs topDocs=indexSearcher.search(query, 100);
int middle=Math.min(start+size, topDocs.totalHits);
for(int i=start;i<middle;i++){
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
int no=scoreDoc.doc;
Document document = indexSearcher.doc(no);
Article article=(Article) LuceneUtil.docuemntToJavaBean(document, Article.class);
articles.add(article);
}
return articles;
}
}
service层:
public class ArticleService {
private ArticleDao articleDao=new ArticleDao();
public Page show(String keywords,int currPageNo)throws Exception{
Page page=new Page();
//封装当前页号
page.setCurrPageNo(currPageNo);
//封装总记录数
int allRecord=articleDao.getAllRecord(keywords);
page.setAllRecordNo(allRecord);
//封装总页数
int allPageNo=0;
if(page.getAllRecordNo()%page.getPerPageSize()==0){
allPageNo=page.getAllRecordNo()/page.getPerPageSize();
}else {
allPageNo=page.getAllRecordNo()/page.getPerPageSize()+1;
}
page.setAllPageNo(allPageNo);
//封装内容
int size=page.getPerPageSize();
int start=(page.getCurrPageNo()-1)*size;
List<Article> articles =articleDao.findAll(keywords, start, size);
page.setArticles(articles);
return page;
}
}
Action层:
public class ArticleServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
try {
//获取关键字
String keywords=request.getParameter("keywords");
if(keywords==null||keywords.trim().length()==0){
keywords="培";
}
//获取当前页号
String temp=request.getParameter("currPageNo");
if(temp==null||temp.trim().length()==0){
temp="1";
}
//调用业务
ArticleService articleService=new ArticleService();
Page page=articleService.show(keywords, Integer.parseInt(temp));
request.setAttribute("page",page);
//将keyword变量绑定到request对象中
request.setAttribute("keywords",keywords);
//转发list.jsp
request.getRequestDispatcher("/list.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
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_3_0.xsd">
<display-name></display-name>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>ArticleServlet</servlet-name>
<servlet-class>com.yxs.lucene.fy.action.ArticleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ArticleServlet</servlet-name>
<url-pattern>/ArticleServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'list.jsp' starting page</title>
</head>
<body>
<!-- 输入区 -->
<form action="${pageContext.request.contextPath}/ArticleServlet" method="POST">
<input id="currPageNOID" type="hidden" name="currPageNo" value="1">
输入关健字:<input type="text" name="keywords" value="${requestScope.keywords}" maxlength="4"/>
<input id="searchKey" type="button" value="站内搜索"/>
</form>
<script type="text/javascript">
function trim(str){
//先去左边空格
str=str.replace(/^\s*/,"");
//再去右边空格
str=str.replace(/\s*$/,"");
return str;
}
document.getElementById("searchKey").οnclick=function(){
//定位表单
var formEle=document.forms[0];
//获取关键字
var keywords=formEle.keywords.value;
keywords=trim(keywords);
if(keywords.length==0){
alert("请输入关键字");
}else{
formEle.submit();
}
}
</script>
<!-- 显示区 -->
<table border="1" align="center" width="60%">
<tr>
<th>编号</th>
<th>标题</th>
<th>内容</th>
</tr>
<c:forEach items="${page.articles}" var="c">
<tr>
<td>${c.id}<td>
<td>${c.title}<td>
<td>${c.content}<td>
</tr>
</c:forEach>
<!-- 分页栏 -->
<tr>
<td colspan="3" align="center">
<a οnclick="fy(1);" style="cursor: hand;">首页</a>
<c:choose>
<c:when test="${requestScope.page.currPageNo+1<=requestScope.page.allPageNo}">
<a οnclick="fy(${requestScope.page.currPageNo+1})" style="cursor: hand;">【下一页】</a>
</c:when>
<c:otherwise>
下一页
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${requestScope.page.currPageNo-1>0 }">
<a style="text-decoration:none;cursor:hand" οnclick="fy(${requestScope.page.currPageNo-1})">【上一页】</a>
</c:when>
<c:otherwise>
上一页
</c:otherwise>
</c:choose>
<a style="text-decoration:none;cursor:hand" οnclick="fy(${requestScope.page.allPageNo})">尾页</a>
</td>
</tr>
</table>
<script type="text/javascript">
function fy(currPageNo){
//定位表单
var formEle=document.forms[0];
alert(currPageNo);
//修改当前页数
formEle.currPageNo.value=currPageNo;
formEle.submit();
}
</script>
</body>
</html>