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里面,结果可想而知了。。

以上就是一个比较简单高效的搜索分页方案。

hibernate-search站内搜索分页解决方案,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。