hibernate-search站内搜索分页解决方案
首先看一下分页的核心类
package go.derek.util; import java.io.Serializable; import java.util.ArrayList; import java.util.List; public class Pager implements Serializable { private static final long serialVersionUID = 2875790409419632498L; private static final int PAGE_DEFAULT_LIMIT = 20; private static final int PAGE_BAR_SIZE = 9; private String query; private int currentPage; private int totalCount; private int totalPage; private int pageLimit; private boolean hasNextPage; private boolean hasPrevPage; private List<String> pageBarList = new ArrayList<String>(); public Pager(int currentPage) { this.currentPage = currentPage; } public void setTotalCount(int totalCount) { if (totalCount <= 0) { return; } this.totalCount = totalCount; if (this.pageLimit <= 0) { this.pageLimit = PAGE_DEFAULT_LIMIT; } if (this.totalCount % this.pageLimit == 0) { this.totalPage = this.totalCount / this.pageLimit; } else { this.totalPage = this.totalCount / this.pageLimit + 1; } if (this.currentPage > this.totalPage) { this.currentPage = this.totalPage; } else if (this.currentPage <= 0) { this.currentPage = 1; } this.setPageBar(); this.hasPrevPage = this.currentPage != 1; this.hasNextPage = this.currentPage != this.totalPage; } //设置页面下方的分页按钮条 public void setPageBar() { if (this.totalPage <= PAGE_BAR_SIZE) { for (int i = 1; i <= this.totalPage; i++) { pageBarList.add(Integer.toString(i)); } } else if (this.currentPage <= PAGE_BAR_SIZE / 2) { for (int i = 1; i <= PAGE_BAR_SIZE; i++) { pageBarList.add(Integer.toString(i)); } } else if (this.currentPage >= this.totalPage - (PAGE_BAR_SIZE - 1) / 2) { for (int i = this.totalPage - PAGE_BAR_SIZE + 1; i <= this.totalPage; i++) { pageBarList.add(Integer.toString(i)); } } else { for (int i = this.currentPage - PAGE_BAR_SIZE / 2; i < this.currentPage - PAGE_BAR_SIZE / 2 + PAGE_BAR_SIZE; i++) { pageBarList.add(Integer.toString(i)); } } } //省略各属性的setter和getter方法
然后在来看一下搜索的核心代码
QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Question.class).get(); //在这里修改要查询的字段 Query luceneQuery = queryBuilder.keyword().onFields("title","content").matching(queryString).createQuery(); FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, Question.class); pager.setTotalCount(fullTextQuery.getResultSize()); pager.setQuery(queryString); fullTextQuery.setFirstResult((pager.getCurrentPage()-1)* pager.getPageLimit()); fullTextQuery.setMaxResults(pager.getPageLimit()); List<Question> rsList = fullTextQuery.list();
其中fullTextQuery.getResultSize()方法可以得到结果集的总量,如果采用集群的话,返回的回是一个约数,可能不是最准确的数字,如果只有一台服务器,那就返回的数字就肯定是准确的了。
然后setFirstResult()和setMaxResult()分别设置每一页的开始下标、每一页显示的记录数。
下面调用的那个list()方法,返回的就只是那一页结果了,也就是pager类里面设置的20个,然后当你点击下一页的时候,会再搜索20个,以此类推。
当数据量非常大的时候,这样做是非常高效的。假设表里有上千万条符合关键词的记录,一下子都放到一个list里面,结果可想而知了。。
以上就是一个比较简单高效的搜索分页方案。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。