Paginação - Melhores opções

10 respostas
C
Olá pessoal,

 iremos desenvolver um sistema e nosso volume de resultados de consulta pode ser razoavelmente grande, por volta de 5000 registros. Gostaria da opinição de vocês para as seguintes questões:
  1. Onde seria melhor implementar a paginação ? No próprio banco de dados, no DAO, na camada de apresentação, etc…

  2. Existem componentes prontos para a resposta da questão 1 ? Quais seriam ?

Qualquer ajuda é bem vinda. Agradeço desde já. :slight_smile:

Calemino.

10 Respostas

Pedrosa

Existe uma taglib que faz essa paginação automática:

http://displaytag.homeip.net/displaytag-examples-1.1/example-paging.jsp

vc retorna uma lista da sua classe DAO e passa via request para o JSP a taglib se vira e monta, e vc define o número de páginas exibidas e além disso ela exporta automaticamente para pdf, xls, csv, rtf.

Pedrosa

No caso de grandes resultados vc precisa fazer alguns ajustes nela, pois ela carrega tudo de uma vez.

M

A melhor opção seria vc fazer no BD, pois a quantidade retornada seria dividida e não tudo numa pancada, pois assim fica mais lento, já paginando no BD fica mais rápido.

Devido a facilidade dê uma estudada:
http://www.guj.com.br/posts/list/35113.java

B

Cara, acho que vc deveria ajustar o seu design para fazer a paginação no banco de dados.

Como já disseram, taglibs e outros componentes só paginam depois que todo o resultado já foi retornado.

Eu usava um esquema assim em consultas grandes: select top 10 * from tabela where id not in(select top 10 tabela.id from tabela)

Ou seja, busque os 10 primeiros registros da tabela “tabela” que não estejam entre os 10 primeiros registros da tabela “tabela”.

daí, para as demais pgs, é só mudar o segundo 10 para 20, 30, 40, 50…

Abraço.

marciobarroso

O melhor a ser feito é a paginação no banco, passando 1 atributo para controle dos registros …

SQL :

int indice = 1;
int qtdeRegistros = 10;

SELECT 
    campos 
FROM 
    (
     SELECT 
        campos, 
        rownum n 
    FROM (
           SELECT 
            campos 
        FROM 
            tabela
             )
     )
WHERE 
    n BETWEEN indice AND indice + qtdeRegistros

Hibernate :

int inicio = 1;
int registros = 10;

String sql = "Select campos from tabela where campo = campo";
Query q = session.createQuery(sql);
q.setFirstResult(inicio);
q.setMaxResults(registros);
Collection resultado = q.list();

Você só precisará criar uma rotina para gerar a qtde de páginas usando a qtde de registros / registros por página e printar os números de páginas com um link passando o indice que será usado pelo select para o java.

falando assim parece easy, mas deu um trabalho implementar isso.

Se quiser, posso te passar o que eu tenho .

Abraço

Z

Depende muito.

Se você sabe que o usuário vai querer ver todas as páginas, é melhor trazer logo tudo e paginar na view. Poupa o trabalho do banco de dados, principalmente se for uma consulta muito pesada (lembrando que consulta pesada != consulta que retorna muitos dados).

Mas, por outro lado, se o cara provavelmente só vai querer ver a primeira página, é melhor paginar logo na consulta.

Analise caso a caso, não há uma solução tamanho único para tudo. O Google, por exemplo, sabe que ninguem vai querer ver a página 87.565 de uma busca, daí ele nem se preocupa em procurar isso, ele só traz as primeiras páginas, sabendo que todo mundo vai parar por ali.

Ironlynx

Fala Pedrosa, resolvi me arriscar com a displaytag!Meu sistema é simples, o usuário se loga no sistema, navega/consulta/insere itens.
Eu tô querendo que na hora que ele faça uma dada pesquisa, retornem 50 resultados(linhas) por página.São ramos de seguro como os abaixo:

public ageris.negocio.RamoDeSeguro retornarRamoDeSeguro(ResultSet rs) throws SQLException {
		ageris.negocio.RamoDeSeguro rds = new ageris.negocio.RamoDeSeguro();
		             rds.setId_tiposeg(rs.getInt("id_tiposeg"));
		             rds.setInicio(rs.getDate("inicio"));
		             rds.setImpo_segurada(rs.getBigDecimal("impo_segurada"));
		             rds.setPremio(rs.getBigDecimal("premio"));
		             rds.setId_seguradora(rs.getInt("id_seguradora"));
		             rds.setId_cobertura(rs.getInt("id_cobertura"));
		             rds.setCorretagem(rs.getInt("corretagem"));
		             rds.setLmi(rs.getBigDecimal("lmi"));
		             rds.setPatrimonio_liq(rs.getBigDecimal("patrimonio_liq"));

		return rds;
	}

	public Collection<ageris.negocio.RamoDeSeguro> retornarColecaoDeRamosDeSeguro(ResultSet rs)
			throws SQLException {
		Collection <ageris.negocio.RamoDeSeguro> rds = new ArrayList <ageris.negocio.RamoDeSeguro>();

		   while(rs.next()){
		      rds.add(retornarRamoDeSeguro(rs));
		   }
		   return rds;
	}

Eu não entendi uma coisa(código da página):

<jsp:scriptlet> Object foo = session.getAttribute( "ramoseg" );
   if( foo == null ) {
      session.setAttribute( "ramoseg", new TestList(100, false) );
   }
</jsp:scriptlet>

  <h3>Ramos cadastrados:</h3>

  <display:table name="sessionScope.ramoseg" pagesize="50">
    <display:column property="id_tiposeg" title="ID" />
    <display:column property="inicio" />
    <display:column property="impo_segurada" />
    <display:column property="premio" />
    <display:column property="corretagem" />
    <display:column property="lmi" />
  </display:table>

O atributo que eu quiser mostrar (na verdade o conjunto de Ramos de Seguros cadastrados), eu tenho que pôr ele na sessão?

fredbh

Tudo bem pessoal, tbm estou com essa duvida… mas gostaria de usar as facilidades oferecidas pelo displaytag…

O problema eh q meu sistema ira retorna quantidades enormes de dados… e o mesmo precisa ser rapido… por eh um sistema basicamente de consulta… com muitos usuarios…

O displaytag ira carregar tudo na memoria e pagina a partir da memoria ?

Quais ajustes devo fazer para q o displaytag pagine via BD ?

Alguma soluçao de cache q posso utilizar ?

Tirando a paginaçao manual… qual outro metodo recomendam para um sistema q eh basicamente buscas… com muitos usuarios( aprox: 100/seg), buscando obj complexos(com relacionamentos). Alguma sugestao ?

Desde ja agradeço
valewww

Pedrosa

Ironlynx, sim jogue o resultado na sessão na primeira vez e crie uma ação de paginar na propriedade requestURI, nessa ação os dados já estarão na sessão, a taglib se vira e monta, não precisando conectar novamente no banco.

<display:table requestURI="servlet?acao=paginarClientes" name="${clientes}" pagesize="10" export="true" class="simple" excludedParams="*">

E o name deve ser o nome que vc atribuiu na sessão, ou seja vc carregou as informações na primeira vez e agora navega com esses dados na sessão.

romuloff

Desenterrando …
Pois gostaria de discutir se displaytag ainda é uma boa opção para paginar e implementar ajax em cima dele pra paginar/ordenar (e tambem se ele ainda é uma boa opção mesmo sem essa necessidade). Pra isso conheço uma solução integrando o displaytag com ajaxtags. Tem + alguma ?
Ou se pra facilitar isso estariam utilizando frameworks javascript/json (jquery, extJS, etc) ?
Eaí, como está o cenário atualmente ?

Criado 4 de julho de 2006
Ultima resposta 8 de jun. de 2009
Respostas 10
Participantes 9