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