Paginação com VRaptor 3

23 respostas
R

Olá a todos!

Gostaria de saber como o pessoal que usa o VRaptor 3 tem feito as suas paginações, em memoria, ou em banco? quais frameworks? alguma implementação simples sugerida?

desde ja obrigado pelas sugestões

abrazzzzzzzzzzzzzzzzzz

23 Respostas

G

Eu criei uma implementação proprietária minha que faz a paginação para mim trazendo na coleção apenas os dados da página atual, porém essas classes são implementações de List e AbstractList. Assim eu tenho uma coleção normal, porém com os dados de paginação.

Criei um gist com essas classes há algum tempo: http://gist.github.com/249508

Lucas_Cavalcanti

pra ajudar a montar a paginação na tela vc pode usar vários frameworks como o displaytag, algum plugin do JQuery ou o ExtJS…

agora qto a parte de fazer na memória ou no banco depende de qtos dados vc for mostrar… se forem poucos faça em memória, se forem muitos faça no banco…

cinei

Uso uma solução própria. Mando para a view a primeira página ou a pagina solicitada.

juniorsatanas

Garcia fui baixar http://gist.github.com/garcia-jj e olhei sua foto, cara feio da porra !

heheh

G

Isso é o stress com a programação e a cachaça!!!
:stuck_out_tongue: :stuck_out_tongue:

juniorsatanas

Até tu brutos ? eu to brincando aqui com Vraptor + Eclipse + GlasFishe + 1 Cachinha de SKOL…

Eu não tenho Stress, pois meus sistemas não tem BUG, a caulpa e do compilador sempre, ou de algum jar corrompido ! hahah

abraço Garcia !

R

Garcia vc poderia me auxiliar na utilizacao da sua paginacao…

nao entendi o Paging.java aonde q entra, to fazendo uma classe de teste…

valeuu!!!

public class TestaPaginacao {

	public static void main(String[] args) {

		PaginatedList<Integer> integerPaginatedList = getIntegerList();
		System.out.println(integerPaginatedList.getTotalSize());
		System.out.println(integerPaginatedList.getCurrentPage());
		System.out.println(integerPaginatedList.getTotalPages());
		System.out.println(integerPaginatedList.getFirstResult());
		
		for (Integer inteiro : integerPaginatedList) {
			System.out.println(inteiro);
		}
		
	}

	
	public static PaginatedList<Integer> getIntegerList() {
		
		PaginatedList<Integer> integerPaginatedList = new PaginatedListWrapper<Integer>();
		
		for (int i = 1; i <= 100; i++) {
			integerPaginatedList.add(i);
		}
		
		return integerPaginatedList;
		
	}
	
}
G

rodrigo.lopes, desculpe a demora, acabei perdendo esse tópico de vista.

Paging é o objeto que guarda as informações de página atual e quantidade de registros por página. Eu uso ela na camada web, algo como:

Paging p = Paging.getInstance(5); // indica que a página atual é a 5.

Essa sugestão de paginação eu uso em um projeto meu, e é bem específico para meu caso. Você terá de adaptar ela conforme teu caso, pois minha intenção não é ter algo genérico.

Esse Paging é enviado até meu repositório de dados, onde eu faço assim conforme a quantidade de registros total eu calculo a paginação:

// calculando navegação
final int currentPage = paging.getCurrentPage();
final int perPage = paging.getPerPage();
final int totalRecords = /* busca a quantidade de registros total */;
final int firstRecord = (currentPage * perPage) - perPage;
final int lastPage = new Double(Math.ceil((double) totalRecords / perPage)).intValue();

// executa a consulta
TypedQuery<T> query = getEntityManager().createQuery(c);
query.setFirstResult(firstRecord);
query.setMaxResults(paging.getPerPage());
List<T> results = query.getResultList();

// wapper de retorno
final PaginatedListWrapper<T> wrapper = new PaginatedListWrapper<T>(results);
wrapper.setCurrentPage(currentPage);
wrapper.setFirstResult(firstRecord);
wrapper.setTotalPages(lastPage);
wrapper.setTotalSize(totalRecords);

return wrapper;

Depois tenho uma taglib que lê esses dados no JSP. Logo mais posso anexar ela no meu gist.

Como você pode notar, essas classes são apenas wrappers para a lista real.

R

E ae garcia… blz!

saquei seu esquema, acabei implementando algo para a minha necessidade tb… funcionou e ficou bem legal…

:wink:

valeu pela atencao

abs

G

Rodrigo, como você fez a sua implementação?

Tenho curiosidade de saber porque até então não sei se a minha abordagem é a melhor. Tentei fazer alguma coisa bem genérica, mas é difícil fazer algo assim, até porque você nunca sabe o que você terá nos seus repositórios e daos, se hibernate, JPA, etc.

R

Garcia,

Como para minha necessidade as listas nao sao gigantes. estou trabalhando com elas em memoria.

Por favor, mande seus comentarios tb… nao sei se é a melhor forma de fazer, porem fiquei satisfeito com o resultado ate entao…

mando esse paginator pra jsp

public class Paginator<T> {

    private List<T> lista;
    private List<T> listaPaginada;
    private Integer quantidadeTotalRegistros;
    private Integer quantidadeTotalPaginas;
    private Integer quantidadeRegistrosPagina;
    private Integer paginaAtual;

    public Paginator(List<T> lista) {
        this.lista = lista;
        this.quantidadeTotalRegistros = lista.size();
        this.quantidadeRegistrosPagina = 10;
        this.paginaAtual = 1;
        this.setQuantidadeTotalPaginas(quantidadeRegistrosPagina);
    }

    public Paginator(List<T> lista, Integer quantidadeRegistroPagina) {
        this.lista = lista;
        this.quantidadeTotalRegistros = lista.size();
        this.quantidadeRegistrosPagina = quantidadeRegistroPagina;
        this.paginaAtual = 1;
        this.setQuantidadeTotalPaginas(quantidadeRegistroPagina);
    }

    public List<T> paginar(Integer pagina) throws Exception {
        List<T> listaPaginada = null;
        this.paginaAtual = pagina;

        if (pagina == 1 || pagina <= 0) {
            if (getQuantidadeTotalRegistros() < quantidadeRegistrosPagina) {
                listaPaginada = lista.subList(0, getQuantidadeTotalRegistros());
            } else {
                listaPaginada = lista.subList(0, quantidadeRegistrosPagina);
            }
        } else {
            Integer inicio = ((pagina - 1) * quantidadeRegistrosPagina);
            Integer fim = inicio + quantidadeRegistrosPagina;

            if (pagina > quantidadeTotalPaginas) {
                inicio = getQuantidadeTotalRegistros() - quantidadeRegistrosPagina;
                listaPaginada = lista.subList(inicio, getQuantidadeTotalRegistros());
            } else if (pagina == quantidadeTotalPaginas) {
                listaPaginada = lista.subList(inicio, getQuantidadeTotalRegistros());
            } else {
                listaPaginada = lista.subList(inicio, fim);
            }
        }

        this.listaPaginada = listaPaginada;

        return listaPaginada;
    }

    public List<T> getLista() {
        return lista;
    }

    public void setLista(List<T> lista) {
        this.lista = lista;
    }

    public List<T> getListaPaginada() {
        return listaPaginada;
    }

    public void setListaPaginada(List<T> listaPaginada) {
        this.listaPaginada = listaPaginada;
    }

    public Integer getQuantidadeTotalRegistros() {
        return this.quantidadeTotalRegistros;
    }

    public void setQuantidadeTotalRegistros(Integer quantidadeTotalRegistros) {
        this.quantidadeTotalRegistros = quantidadeTotalRegistros;
    }

    public Integer getQuantidadeTotalPaginas() {
        return quantidadeTotalPaginas;
    }

    private void setQuantidadeTotalPaginas(Integer quantidadeRegistroPagina) {
        if ((getQuantidadeTotalRegistros() % quantidadeRegistroPagina) == 0) {
            this.quantidadeTotalPaginas = getQuantidadeTotalRegistros() / quantidadeRegistroPagina;
        } else {
            this.quantidadeTotalPaginas = (getQuantidadeTotalRegistros() / quantidadeRegistroPagina) + 1;
        }
    }

    public Integer getQuantidadeRegistrosPagina() {
        return quantidadeRegistrosPagina;
    }

    public void setQuantidadeRegistrosPagina(Integer quantidadeRegistrosPagina) {
        this.quantidadeRegistrosPagina = quantidadeRegistrosPagina;
    }

    public Integer getPaginaAtual() {
        return paginaAtual;
    }

    public void setPaginaAtual(Integer paginaAtual) {
        this.paginaAtual = paginaAtual;
    }

}

Um teste…

public class PaginatorTest {

    public static void main(String[] args) throws Exception {
        List<Integer> lista = getIntegerList();
        Paginator<Integer> paginator = new Paginator<Integer>(lista);

        lista = paginator.paginar(3);

        for (Integer numero : lista) {
            System.out.println(numero);
        }
        
        System.out.println();
        System.out.println("Quantidade total de registros: " + paginator.getQuantidadeTotalRegistros());
        System.out.println("Quantidade total de páginas: " + paginator.getQuantidadeTotalPaginas());
        System.out.println("Quantidade de registros por página: " + paginator.getQuantidadeRegistrosPagina());
        System.out.println("Página atual: " + paginator.getPaginaAtual());
    }


    public static List<Integer> getIntegerList() {
        List<Integer> integerPaginatedList = new ArrayList<Integer>();

        for (int i = 1; i <= 112; i++) {
            integerPaginatedList.add(i);
        }

        return integerPaginatedList;
    }

}
R

E ae garcia? o que te parece?

juniorsatanas

Ele ficou sem palavras, teu código e otimo… ai ele deu um Control + C Control + V e deletou o dele… VIVA

G

Rodrigo, para o propósito de usar a lista em memória a classe me pareceu boa. E como você disse, não terá problemas com muitos dados em memória.

O problema que eu penso em usar memória é que você tem que ficar controlando quando deve descarregar da memória os dados. Um exemplo é o usuário entrou na tela, listou os clientes e depois foi para a tela de listar pagamentos. Assim você tem duas listas em memória. E como saber quando derrubar os objetos desnecessários.

Além disso há o problema de que um registro pode ser apagado dessa lista ou adicionado outros. Assim o usuário terá sempre uma lista out-of-date.

Eu tenho trabalhado com projetos onde a quantidade de usuários simultaneos é grande, então memória é sempre um problema, mesmo usando clusters. No meu caso a estratégia de sempre pesquisar no banco de dados aliado a estatégias de cache via second-level-cache do JPA têm me deixado mais satisfeito.

Não é teu caso, mas vale para alguma experiência futura que você tenha.

G

Rodrigo, esqueci de uma coisa… Sua classe de teste pode melhorar. Você pode usar o JUnit para validar os resultados. Assim quando você roda os testes ele te mostra barras verde ou vermelhas conforme o teste passou ou não.

No seu caso você pode por exemplo fazer um teste com 100 registros usando páginação de 20 em 20. Então seu teste se consiste em testar se foram retornados os registros nas páginas corretas, se a quantidade de páginas está correto… e tudo mais.

Mas que isso, Junior?! Quanta raiva nesse coração. Hahahahahahha. Vamos tomar uma gelada que passa. :smiley:

juniorsatanas

garcia-jj tu sabes que e bricadeira para te provocar… Você é Meu camarada… Eu pago a Gela !

R

Ae galera blz!

Garcia, valeu pelas observacoes, concordo totalmente com o que vc falou…

Porem estou trabalhando com um site web, esta paginacao que eu faco conta com um total de ± 500 registros e estes subdivididos, por exemplo, tenho 500 objetos para listar, mas isso nunca ocorrera, o usuario lista as informações de um bairro por exemplo, e retorna uns 20, 30 registros de uma vez, sacou?

essa lista de 500 nao muda toda hroa…

mas estou pensando em fazer algo mais dinamico e talvez usar a paginacao de bd, com o criteria, por enqto vo deixar assim, sabe como é ne, prazos… rs

abs

Leandro-SP

Será que é possivel fazer paginação via Criteria dentro do DAO?
Passando como parametro a pagina atual, a quantidade de registros maxima da pagina e talvez até um filtro para um determinado campo?

Aguardo resposta.
Obrigado.
Att,
Leandro.

Guevara

Oi Leandro!
Com Criteria vc pode setar a quantidade de resultados, tipo:

@SuppressWarnings("unchecked")
	public List<Produto> listaTopDez() {
		return session.createCriteria(Produto.class)		
		.addOrder(Order.desc("dtInclusao")).setMaxResults(10).list();
	}

Retornando os 10 últimos produtos cadastrados.
Têm uns exemplos de um livro aqui bem legais.
Veja um trecho:

Abraço!

Leandro-SP

Guevara:
Oi Leandro!
Com Criteria vc pode setar a quantidade de resultados, tipo:

@SuppressWarnings("unchecked")
	public List<Produto> listaTopDez() {
		return session.createCriteria(Produto.class)		
		.addOrder(Order.desc("dtInclusao")).setMaxResults(10).list();
	}

Retornando os 10 últimos produtos cadastrados.
Têm uns exemplos de um livro aqui bem legais.
Veja um trecho:

Abraço!

Ae Guevara,
Funcionou!

public List<Produto> listaTudo(int first, int max) { Criteria criteria = this.session.createCriteria(Produto.class); criteria.addOrder(Order.asc("nome")); criteria.setFirstResult(first); criteria.setMaxResults(max); return criteria.list(); }

Sendo que no Controller, eu chamo com os parametros do meu Flexigrid:

first = ((page-1)*rp)+1; max = rp;

A resposta vai via json para o JSP.

Obrigado.
Att,
Leandro.

C
rodrigo.lopes:
Garcia,

Como para minha necessidade as listas nao sao gigantes. estou trabalhando com elas em memoria.

Por favor, mande seus comentarios tb... nao sei se é a melhor forma de fazer, porem fiquei satisfeito com o resultado ate entao....

mando esse paginator pra jsp

public class Paginator<T> {

    private List<T> lista;
    private List<T> listaPaginada;
    private Integer quantidadeTotalRegistros;
    private Integer quantidadeTotalPaginas;
    private Integer quantidadeRegistrosPagina;
    private Integer paginaAtual;

    public Paginator(List<T> lista) {
        this.lista = lista;
        this.quantidadeTotalRegistros = lista.size();
        this.quantidadeRegistrosPagina = 10;
        this.paginaAtual = 1;
        this.setQuantidadeTotalPaginas(quantidadeRegistrosPagina);
    }

    public Paginator(List<T> lista, Integer quantidadeRegistroPagina) {
        this.lista = lista;
        this.quantidadeTotalRegistros = lista.size();
        this.quantidadeRegistrosPagina = quantidadeRegistroPagina;
        this.paginaAtual = 1;
        this.setQuantidadeTotalPaginas(quantidadeRegistroPagina);
    }

    public List<T> paginar(Integer pagina) throws Exception {
        List<T> listaPaginada = null;
        this.paginaAtual = pagina;

        if (pagina == 1 || pagina <= 0) {
            if (getQuantidadeTotalRegistros() < quantidadeRegistrosPagina) {
                listaPaginada = lista.subList(0, getQuantidadeTotalRegistros());
            } else {
                listaPaginada = lista.subList(0, quantidadeRegistrosPagina);
            }
        } else {
            Integer inicio = ((pagina - 1) * quantidadeRegistrosPagina);
            Integer fim = inicio + quantidadeRegistrosPagina;

            if (pagina > quantidadeTotalPaginas) {
                inicio = getQuantidadeTotalRegistros() - quantidadeRegistrosPagina;
                listaPaginada = lista.subList(inicio, getQuantidadeTotalRegistros());
            } else if (pagina == quantidadeTotalPaginas) {
                listaPaginada = lista.subList(inicio, getQuantidadeTotalRegistros());
            } else {
                listaPaginada = lista.subList(inicio, fim);
            }
        }

        this.listaPaginada = listaPaginada;

        return listaPaginada;
    }

    public List<T> getLista() {
        return lista;
    }

    public void setLista(List<T> lista) {
        this.lista = lista;
    }

    public List<T> getListaPaginada() {
        return listaPaginada;
    }

    public void setListaPaginada(List<T> listaPaginada) {
        this.listaPaginada = listaPaginada;
    }

    public Integer getQuantidadeTotalRegistros() {
        return this.quantidadeTotalRegistros;
    }

    public void setQuantidadeTotalRegistros(Integer quantidadeTotalRegistros) {
        this.quantidadeTotalRegistros = quantidadeTotalRegistros;
    }

    public Integer getQuantidadeTotalPaginas() {
        return quantidadeTotalPaginas;
    }

    private void setQuantidadeTotalPaginas(Integer quantidadeRegistroPagina) {
        if ((getQuantidadeTotalRegistros() % quantidadeRegistroPagina) == 0) {
            this.quantidadeTotalPaginas = getQuantidadeTotalRegistros() / quantidadeRegistroPagina;
        } else {
            this.quantidadeTotalPaginas = (getQuantidadeTotalRegistros() / quantidadeRegistroPagina) + 1;
        }
    }

    public Integer getQuantidadeRegistrosPagina() {
        return quantidadeRegistrosPagina;
    }

    public void setQuantidadeRegistrosPagina(Integer quantidadeRegistrosPagina) {
        this.quantidadeRegistrosPagina = quantidadeRegistrosPagina;
    }

    public Integer getPaginaAtual() {
        return paginaAtual;
    }

    public void setPaginaAtual(Integer paginaAtual) {
        this.paginaAtual = paginaAtual;
    }

}

Um teste...

public class PaginatorTest {

    public static void main(String[] args) throws Exception {
        List<Integer> lista = getIntegerList();
        Paginator<Integer> paginator = new Paginator<Integer>(lista);

        lista = paginator.paginar(3);

        for (Integer numero : lista) {
            System.out.println(numero);
        }
        
        System.out.println();
        System.out.println("Quantidade total de registros: " + paginator.getQuantidadeTotalRegistros());
        System.out.println("Quantidade total de páginas: " + paginator.getQuantidadeTotalPaginas());
        System.out.println("Quantidade de registros por página: " + paginator.getQuantidadeRegistrosPagina());
        System.out.println("Página atual: " + paginator.getPaginaAtual());
    }


    public static List<Integer> getIntegerList() {
        List<Integer> integerPaginatedList = new ArrayList<Integer>();

        for (int i = 1; i <= 112; i++) {
            integerPaginatedList.add(i);
        }

        return integerPaginatedList;
    }

}
Estou como dificuldade de implementar paginacão no vraptor.

Como vc implementou no Vrator e view essa classe?

juniorsatanas

boa pergunta…

dserodio

garcia-jj:
Eu criei uma implementação proprietária minha que faz a paginação para mim trazendo na coleção apenas os dados da página atual, porém essas classes são implementações de List e AbstractList. Assim eu tenho uma coleção normal, porém com os dados de paginação.

Criei um gist com essas classes há algum tempo: http://gist.github.com/249508


Garcia,

Esse gist foi excluído, onde posso encontrar essas classes?

Criado 11 de maio de 2010
Ultima resposta 13 de abr. de 2011
Respostas 23
Participantes 9