Paginação de Dados com VRaptor + Hibernate + Displaytag

14 respostas
M

Pessoal, estou usando VRaptor + Hibernate + Displaytag para listar dados e percebi que simplesmente setando a propriedade pagesize=“50” da displaytag, ele lista todos os registros, por exemplo, se tiver 100.000 registros, ele pega todos e só depois ele pagina, deixando muito lenta a página no momento de listar !!!

Como eu posso fazer para, alé de paginar na displaytag, paginar no List preenchido no meu DAO ??

Valew.

14 Respostas

A

Você tem que mudar seu método de busca para trazer somente os registros que quer mostrar.

Por exemplo, usando um limit na query SQL.

M

Como eu faria isso usando hibernate ??

Veja meu método:

public List<T> listaTudo(){
	return this.session.createCriteria(this.classe).list();
}

Valew.

A
public List<T> listaTudo(){
	return this.session.createCriteria(this.classe).setMaxResults(1).list();
}

É um jeito de fazer. Na verdade você vai ter que combinar isso com o setFirstResult, mas dizer onde começar.

Talvez tenha um jeito de fazer usando .scroll() ao invés de .list(). Dê uma olhada na API.

M

Mas…como eu faria para ordenar coluna e paginar na displaytag e sincronizar isso no meu método ?? teria algum parâmetro que tenho que passar da displaytag ??

Valew.

M

Desculpe insistir, mas preciso… e não vou abrir outro tópico com a mesma dúvida !!!

Alguém tem alguma dica sobre a colocação citada acima ?

Valew

juniorsatanas

Estou com o mesmo problema, se alguem sabe como fazer da uma dica ai !

juniorsatanas

Bom eu gostaria de listar somente 10 registro por vez, e fazer um link avança e outro voltar, alguem pode ajduar ?

algumas tentativas:


clientes.java

public void lista() {

usuarios = this.daoFactory.getClientesDao().listaTodos();

}

Dao.java

public List<T> listaTodos(){

return this.session.createCriteria(this.type).setMaxResults(10).list();

}

************************************* o problema que ele só mostra 10, agora quero fazer um link para mostra os proximos !

juniorsatanas

não conseguir ainda !

cassio

:arrow: Com o setMaxResults() defina o tamanho da página
:arrow: Use um contador para controlar as páginas exibidas (pág. 1, pág. 2, etc)
:arrow: Com o setFirstResult() defina qual será o primeiro item retornado a cada página. Algo como

int page = -1;
int pageSize = 20;
//...
return this.session.createCriteria(this.type).setMaxResults(pageSize).setFirstResult((page+1) * pageSize).list();

Aqui eu coloco a variável page na sessão do usuário. Coloco um link para avançar na tabela e outro para retroceder. Tenho um método paginar que recebe um enum que indica FORWARD ou REWARD, indicando se devo ir pra frente ou pra trás. Pego a variável page na sessão e faço +1 ou -1 conforme a necessidade.

rodrigo_corinthians
<html:hidden property="pageNumber" styleId="pageNumber" value="0" />
Propriedade pageNumber que contém o número da página.
<display:table name="${simpleList}" id="tableList" export="true" pagesize="10" class="simple" requestURIcontext="false" requestURI="?act=searchPaginator" excludedParams="*">
    <display:column titleKey="label.personId" sortable="true" headerClass="sortable" style="width: 50%; height: 18">
    	<html:link href="javascript:doEdit(${count});"><c:out value="${tableList.personId}" /></html:link>
    </display:column>
    <display:column titleKey="label.name" sortable="true" headerClass="sortable" style="width: 50%; height: 18">
		<c:out value="${tableList.name}" />
    </display:column>
</display:table>
Propriedade requestURI contém o método que tratará a paginação.
<script>
/* Altera a chamada dos links do displaytag */
function replaceLinks(tableList) {
	if(!isSmartphone()){
		if($(tableList)){
			var sortLinks = $(tableList).getElementsByTagName('thead')[0]
			                             .getElementsByTagName('a');
			ajaxLinks(sortLinks, true);
			if (document.getElementsByClassName('pagelinks').length > 0) {
			    var pagelinks = document.getElementsByClassName('pagelinks')[0]
			                            .getElementsByTagName('a');
			    ajaxLinks(pagelinks, false);
			}

			if(document.getElementsByClassName('exportlinks').length > 0){
			    var links = document.getElementsByClassName('exportlinks')[0]
			                            .getElementsByTagName('a');
			    exportLinks(links);
			}
		}
	}
}

/* Altera a chamada dos links da exportação dinamicamente */
function exportLinks(links) {
	for (i=0; i < links.length; i++) {
	    links[i].onclick = function() {
			var url = this.href;
			url += "&pageNumber="+getPageNumber(this.href);
			url += "&export=true";
			var windowFocus = window.open(url, 'export', '');
			windowFocus.focus();
			return false;
	    }
	}
}

/* Altera a chamada dos links da paginação dinamicamente */
function ajaxLinks(links, sort) {
	for (i=0; i < links.length; i++) {
	    links[i].onclick = function() {
			var url = this.href;
			var pars = "pageNumber=";
			if(sort){
				pars += $("pageNumber").value;
			} else {
				pars += getPageNumber(this.href);
			}
			var myAjax = new Ajax.Request(
				url, 
				{
					method: 'post',
					parameters: pars, 
					onFailure: showError,
					onComplete: showRequest
				});
			return false;
	    }
	}
}

/* Seta o número da pagina */
function getPageNumber(stringUrl) {
	var pageNumber = 1;
	if(stringUrl != ""){
		var splitUrl = stringUrl.split("=");
		pageNumber = (parseInt(splitUrl[splitUrl.length - 1], 10) - 1);
		$("pageNumber").value = pageNumber;
	}
	return pageNumber;
}

replaceLinks("tableList");
</script>
Javascript para alterar os links dinamicamente depois que renderiza na tela.
public ActionForward searchPaginator(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception {
		try {
			String export = request.getParameter("export");
			if(export != null && export.equals("true")){
				return doExport(actionMapping, actionForm, request, response);
			}
			SimpleDynaValidatorForm simpleDynaValidatorForm = (SimpleDynaValidatorForm) actionForm;
			SimpleBean simpleBean = getBeanView();
			BeanUtils.copyProperties(simpleBean, simpleDynaValidatorForm);
			SimpleCriteriaExpression expression = new SimpleCriteriaExpression(simpleBean.getClass());
			expression.addFilters(SimpleUtil.getMapAttribute(simpleBean), true);
			SimplePage page = new SimplePage();
			int pageNumber = 0;
			String parameterPage = request.getParameter("pageNumber");
			try {
				if(parameterPage != null && !parameterPage.equals("")){
					pageNumber = Integer.parseInt(parameterPage);
				} else if(isSmartphone()){
					if(request.getQueryString() != null && !request.getQueryString().equals("")){
						String[] splitUrl = request.getQueryString().split("=");
						pageNumber = (Integer.parseInt(splitUrl[splitUrl.length - 1]) - 1);
					}
				}
			} catch(NumberFormatException nfe) {}
			request.setAttribute("pageNumber", new Integer(pageNumber));
			page.setPageNumber(pageNumber);
			page.setMaxItens((getMaxItens() > 0 ? getMaxItens() : 10));
			expression.setPage(page);
			List simpleList = new SimplePojoService().get(expression);
			if(simpleList != null && !simpleList.isEmpty()){
				Long countPage = (Long) request.getSession().getAttribute(COUNT_PAGE);
				if(countPage != null && countPage > 0){
					List simpleListTotal = new ArrayList(countPage.intValue());
					int maxItens = (getMaxItens() > 0 ? getMaxItens() : 10);
					for(int i = 0; i < countPage; i++){
						if(i == (pageNumber * getMaxItens())){
							simpleListTotal.addAll(simpleList);
							if(simpleListTotal.size() == countPage){
								break;
							}
						}
						if((countPage - maxItens) > i || i < (pageNumber * getMaxItens())){
							simpleListTotal.add(null);
						} else {
							break;
						}
					}
					request.setAttribute("simpleList", simpleListTotal);
				} else {
					request.setAttribute("simpleList", simpleList);
				}
				SimpleSort[] simpleSorts = getSimpleSort();
				if(simpleSorts != null){
					List list = (List) request.getAttribute(SIMPLE_LIST);
					if(list != null && !list.isEmpty()){
						SimpleUtil.sort(simpleSorts, getBeanView().getClass(), list);
						list = null;
					}
				}
			}
		} catch(Exception e) {
			e.printStackTrace();
			throw e;
		}
		return actionMapping.findForward((isSmartphone() ? FORWARD_HOME : FORWARD_RESULT));
	}
Por último o método que controla a paginação, detalhe o tamanho do List sempre é o valor total de registros mas os objetos populados ficam apenas na posição referente ao link da paginação...

Vê se esses pedaços de scripts conseguem te ajudar usei Struts, Hibernate e Ajax(prototype) caso queira posso tentar criar uma versão demo dele...

Sem mais, Rodrigo.

juniorsatanas

Rodrigo Obrigado Vou fazer aqui ! grande abraço para os 2 que ajduaram !

abelgomes

Rodrigo, tem como eu exportar essa lista sem coloca-la na sessao, ja esta tudo configurado e funcionanado perfeitamente, paginação etc…mas na hora de exportar para pdf ou excel da esse erro:
http://www.guj.com.br/posts/list/105706.java

mas se eu colocar o objeto na sessao fica show de bola…

alguma dica pra eu tirar essa lista da sessao?

rodrigo_corinthians

Essas exportações são do próprio displaytag né?

Se a resposta acima for sim você pode extender as classes default(BaseExportView e PdfView) e alterar acrescentar as keys no displaytag.
export.excel.class=SuaClassCustomizadaExcel
export.pdf.class=SuaClassCustomizadaPdf

Se a resposta for não vai dar mais trabalho mas pode usar POI pra gerar o excel e Itext, jasper para gerar os pdf’s.

abelgomes

a resposta é sim… mas como assim? as minhas classes bean(entity,VO)? vao exterder dela?nao entendi muito bem…poderia me dar uma dica ou mostrar algum exemplo… valeu…

Criado 12 de junho de 2007
Ultima resposta 9 de out. de 2008
Respostas 14
Participantes 6