学完了CRUD,对Lucene的了解也比较熟悉了,做一次分页查询加深理解
1. 步骤
使用MVC模型进行分页查询并显示在JSP页面上
2. 要求
输入关键词,查询并且分页显示
3. 创建包结构
3.1 Bean层
3.1.1 PageBean分类的包装类
package com.bart.lucene.pagedemo.bean;
import java.util.List;
/**
* 分页的封装类
*/
public class PageBean <T>{
private int page;//当前页数
private int totalCount;//总记录数
private int totalPage;//总页数
private int limit;//每页显示数据数
private List<T>list;//每页显示数据的集合
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
3.1.2 Article文章类
package com.bart.lucene.pagedemo.bean;
/**
* 文章
* @author hp
*
*/
public class Article {
@Override
public String toString() {
return "Article [id=" + id + ", title=" + title + ", content="
+ content + "]";
}
private Integer id;
private String title;
private String content;
public Article(){}
public Article(Integer id, String title, String content) {
super();
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;
}
}
3.2 Dao层
package com.bart.lucene.pagedemo.dao;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import com.bart.lucene.pagedemo.bean.Article;
import com.bart.lucene.util.LuceneUtils;
public class ArticleDao {
/**
* 根据关键词得到所有真实结果,并不是MAX_RECORD=100
* @param keywords
* @return
*/
public int getCountByKeyWord(String keywords) throws Exception{
// 2. 创建indexSearcher
IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.getDirectory());
// 3. 创检查询解析器对象
QueryParser queryParser = new QueryParser(LuceneUtils.getVersion(),"content",LuceneUtils.getAnalyzer());
// 4. 创建对象封装查询关键字
Query query = queryParser.parse(keywords);
// 5. 查询
int MAX_RECORD=100;//取查询结果的前100个,不到100个以实际的为准
TopDocs topDocs = indexSearcher.search(query, MAX_RECORD);
// 6. 返回真实的所有结果
return topDocs.totalHits;
}
/**
* 根据关键字得到Article集合
* @param keywords
* @param begin
* @param limit
* @return
*/
public List<Article> findByKeyWord(String keywords, int begin, int limit) throws Exception {
List<Article>list = new ArrayList<Article>();
// 2. 创建indexSearcher
IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.getDirectory());
// 3. 创检查询解析器对象
QueryParser queryParser = new QueryParser(LuceneUtils.getVersion(),"content",LuceneUtils.getAnalyzer());
// 4. 创建对象封装查询关键字
Query query = queryParser.parse(keywords);
// 5. 查询
int MAX_RECORD=100;//取查询结果的前100个,不到100个以实际的为准
TopDocs topDocs = indexSearcher.search(query, MAX_RECORD);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
Document document = null;
ScoreDoc scoreDoc = null;
// 6. 遍历topdocs查询结果,使用middle变量解决查询越界错误
int middle = Math.min(begin + limit,scoreDocs.length);
for (int i = begin; i < middle; i++) {
scoreDoc = scoreDocs[i];
int no = scoreDoc.doc;
document = indexSearcher.doc(no);
list.add(LuceneUtils.document2JavaBean(document, Article.class));
}
return list;
}
//测试OK
public static void main(String[] args) {
ArticleDao articleDao = new ArticleDao();
try {
System.out.println(articleDao.getCountByKeyWord("电脑"));//6
System.out.println("第一页");
List<Article>list = articleDao.findByKeyWord("电脑", 0,3);
for(Article a : list){
System.out.println(a);
}
System.out.println("第二页");
list = articleDao.findByKeyWord("电脑", 4,7);
for(Article a : list){
System.out.println(a);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.3 Service层
package com.bart.lucene.pagedemo.service;
import java.util.List;
import com.bart.lucene.pagedemo.bean.Article;
import com.bart.lucene.pagedemo.bean.PageBean;
import com.bart.lucene.pagedemo.dao.ArticleDao;
/**
* ArticleService业务层
* @author hp
*
*/
public class ArticleService {
ArticleDao articleDao = new ArticleDao();
public PageBean<Article> getPage(String keywords, int parseInt) throws Exception {
PageBean<Article>pageBean = new PageBean<Article>();
pageBean.setPage(parseInt);
int limit = 3;
pageBean.setLimit(limit);
int totalCount = articleDao.getCountByKeyWord(keywords);
pageBean.setTotalCount(totalCount);
int totalPage = (int)Math.ceil(totalCount*1.0/limit);
pageBean.setTotalPage(totalPage);
int begin = (parseInt-1)*limit;
List<Article>list = articleDao.findByKeyWord(keywords,begin,limit);
pageBean.setList(list);
return pageBean;
}
}
3.4 Action层
这里没用到spring或者struts,直接使用原声的Servlet替代
package com.bart.lucene.pagedemo.action;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.bart.lucene.pagedemo.bean.Article;
import com.bart.lucene.pagedemo.bean.PageBean;
import com.bart.lucene.pagedemo.service.ArticleService;
/**
* ArticleAction类
* 实际上是一个Servlet
* @author hp
*
*/
public class ArticleAction extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
req.setCharacterEncoding("UTF-8");
//获取关键字
String keywords = req.getParameter("keywords");
if(keywords == null && keywords.trim().length() == 0){
//表示查询的关键词为空,跳转到
req.setAttribute("error","请输入查询关键词");
//请求重定向,url改变
resp.sendRedirect(req.getContextPath()+"/list.jsp");
//req.getRequestDispatcher("/list.jsp").forward(req, resp);
}
//获取页码
String page = req.getParameter("page");
if (page == null && page.length() == 0) {
//默认值
page = "1";
}
//调用Service业务层
ArticleService articleService = new ArticleService();
PageBean<Article>pageBean = articleService.getPage(keywords,Integer.parseInt(page));
//将pageBean对象绑定到request对象中
req.setAttribute("pageBean", pageBean);
//将keywords绑定在request对象中
req.setAttribute("keywords", keywords);
//转发到list.jsp
req.getRequestDispatcher("/list.jsp").forward(req, resp);
} catch (Exception e) {
}
}
}
3.5 web.xml
这一步别忘记了配置Servlet
<servlet>
<servlet-name>ArticleAction</servlet-name>
<servlet-class>com.bart.lucene.pagedemo.action.ArticleAction</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ArticleAction</servlet-name>
<url-pattern>/ArticleAction</url-pattern>
</servlet-mapping>
4. 测试
启动Tomcat服务器,在浏览器输入:
http://localhost:8088/Lucene01/list.jsp进入jsp页面,输入电脑,并查询,分页显示结果。数据在上一篇博文的讲解中已经存入了。
5. 总结
- PageBean封装类的使用,代码复用性的好处
- Servlet的回顾和使用
- Lucene的分页查询