Lucene學習總結二

一)       創建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>


發佈了56 篇原創文章 · 獲贊 7 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章