Paginação com Vraptor

6 respostas
T

Salve, estou a implementar paginação usando datatables.net com Vraptor.

Consegui listar os dados e buscar atráves de uma lista JSON, porém não compreendi como "passar" pro vraptor á pagina atual, para buscar os dados somente da página em exibição.
Ex: ele está buscando 1000 registros aonde na tela eu quero permitir apenas 10 em 10.

Abaixo os tópicos no qual me basei, caso alguém tiver alguma outra opção melhor é bem vinda :).
http://www.guj.com.br/java/289553-resolvido-vraptor-paginacao/
http://www.guj.com.br/java/207650-geracao-de-jsonarray-via-vraptor

//DataTables//
public abstract class DataTables {  
    private List< List<String> >aaData;  
    private long iTotalRecords;  
    private long iTotalDisplayRecords;  
    private int minSearch;  
  
    @Override  
    public String toString() {  
        return "{'minSearch':" + minSearch + ", 'iTotalRecords':"  
                + iTotalRecords + ", 'iTotalDisplayRecords':"  
                + iTotalDisplayRecords + ", 'aaData':" + aaData.toString()  
                + "}";  
    }  
  
    @Override  
    public boolean equals(Object obj) {  
        if (obj == null)  
            return false;  
  
        return this.hashCode() == obj.hashCode();  
    }  
  
    @Override  
    public int hashCode() {  
        return this.toString().hashCode();  
    }
//Controller//
@Get("/jtable/paginar/")
    public void paginate() {
			
		List<Cliente> cls = clienteDao.findAll(); //clienteDao.findAll(start, lenght);
	    List<Object[]> listaTratada = new ArrayList<Object[]>();  
	    for (Cliente cli : cls) {  
	        
	        String[] linha = {  cli.getCodigo().toString(),  
	                            cli.getRazaoSocial(), 
	                            cli.getFantasia()
	                         };  
	        listaTratada.add(linha);  
	    }  
	    
	    TableModel dataTable = new TableModel();
	    dataTable.setsEcho(new Long(new Date().getTime()).toString());  
	    dataTable.setiTotalRecords((long)  cls.size());  
	    dataTable.setiTotalDisplayRecords(10);  
	    dataTable.setAaData(listaTratada.toArray()); 
	    
	    result.use(Results.json()).withoutRoot().from(dataTable).include("aaData").serialize();   
    }
//View//
script type='text/javascript'>
	$(document).ready(function() {
		oTable = $('#cliente').dataTable({ //configuração e inicialização do plugin datatables.net
			
			"bAutoWidth":true,
			"bLengthChange": false,
			"bPaginate": true,
			"bFilter": true,
			"bSort": true,
			"bInfo": true,
			"bJQueryUI": false,
			"sPaginationType": "full_numbers",
                        "iDisplayLength":  10,
			 "aLengthMenu": [[10, 100, -1], [10, 100, "All"]],
			 "bProcessing": false,
			 "bServerSide": true,
                          "sAjaxSource": '${pageContext.request.contextPath}/cliente/jtable/paginar/',
             		
		});
	});
	</script>

6 Respostas

Rafael_Guerreiro

Não busque tudo do seu banco de dados para depois filtrar só o que vc precisa. Assim você vai trazer 1000 registros toda vez e só pegar 10 dai.

Primeiro: Você precisa receber os parâmetros que o dataTables vai mandar para você. Ele vai mandar: String minSearch, String sEcho, int iDisplayStart, int iDisplayLength.

Então, você consegue usar esses parâmetros para filtrar a sua busca:

// Se estiver usando Hibernate
session.createCriteria(Cliente.class).add(Restrinctions.ilike("nome", minSearch, MatchMode.ANYWHERE)).setFirstResult(iDisplayStart).setMaxResults(iDisplayLength).list();

Você vai precisar fazer 1 count na base para poder usar no iTotalRecords:

// Se estiver usando Hibernate
(Long) session.createCriteria(Cliente.class).setProjection(Projections.countDistinct("id")).uniqueResult();

Com isso, o próprio DataTables manda os valores certos para você.

T

Rafael, consegui a paginação, era mais simples que eu imaginava, estava tentando capturar a página lá na view, por ajax.

Então, agora que está paginando certo, a ordenação das colunas não está de acordo, sabe o que pode ser?

Segue como ficou o Controller
@Get("/jtable/paginar/")
    public void paginate(String minSearch, String sEcho, int iDisplayStart, int iDisplayLength) {
		
		List<Cliente> cls = clienteDao.findAll(iDisplayStart, iDisplayLength);
	    List<Object[]> listaTratada = new ArrayList<Object[]>();  
	    for (Cliente cli : cls) {  
	        
	        String[] linha = {  cli.getCodigo().toString(),  
	                            cli.getRazaoSocial(), 
	                            cli.getFantasia()
	                         };  
	        listaTratada.add(linha);  
	    }  
	    
	    TableModel dataTable = new TableModel();
	    dataTable.setsEcho(new Long(new Date().getTime()).toString());  
	   
	    dataTable.setiTotalRecords(cls.size());  
	    dataTable.setiTotalDisplayRecords(clienteDao.findAll().size());  
	    
            dataTable.setAaData(listaTratada.toArray()); 
	    
	    result.use(Results.json()).withoutRoot().from(dataTable).include("aaData").serialize();   
    }

E vou verificar pra fazer o total (count) por critéria, estou trazendo todas as colunas desnecessariamente, usando JPA.

Rafael_Guerreiro
tiago.javaman:
Rafael, consegui a paginação, era mais simples que eu imaginava, estava tentando capturar a página lá na view, por ajax.

Então, agora que está paginando certo, a ordenação das colunas não está de acordo, sabe o que pode ser?


Você precisa ver como o DataTables está informando a ordenação e receber no seu método. Depois de receber, você precisa colocar a ordenação no seu select.

tiago.javaman:
Segue como ficou o Controller
@Get("/jtable/paginar/")
    public void paginate(String minSearch, String sEcho, int iDisplayStart, int iDisplayLength) {
		
		List<Cliente> cls = clienteDao.findAll(iDisplayStart, iDisplayLength);
	    List<Object[]> listaTratada = new ArrayList<Object[]>();  
	    for (Cliente cli : cls) {  
	        
	        String[] linha = {  cli.getCodigo().toString(),  
	                            cli.getRazaoSocial(), 
	                            cli.getFantasia()
	                         };  
	        listaTratada.add(linha);  
	    }  
	    
	    TableModel dataTable = new TableModel();
	    dataTable.setsEcho(new Long(new Date().getTime()).toString());  
	   
	    dataTable.setiTotalRecords(cls.size());  
	    dataTable.setiTotalDisplayRecords(clienteDao.findAll().size());  
	    
            dataTable.setAaData(listaTratada.toArray()); 
	    
	    result.use(Results.json()).withoutRoot().from(dataTable).include("aaData").serialize();   
    }
E vou verificar pra fazer o total (count) por critéria, estou trazendo todas as colunas desnecessariamente, usando JPA.
Isso mesmo, faltou você considerar o minSearch para filtrar. Ah, essa linha:
dataTable.setsEcho(new Long(new Date().getTime()).toString());
Tem que ficar assim:
dataTable.setsEcho(sEcho);
T

Consegui com “sSearch” ao invés de “minSearch” nos parâmetros, ele estava retornando null.

Rafael, não existe alguma maneira mais simples de transformar a lista de objetos em string, com MAP, algo assim? para tornar o código mais flexivel.

T

Rafael, estou me referindo a lista de objetos -> String, se tem outra forma de montar a lista mais dinamicamente.

A paginação está funcionando perfeitamente, desde já agradeço pela força.

Willian_Antunes

Para quem estiver navegando por aqui, fiz um tutorial passo a passo explicando como usar o DataTables e com laboratório pronto no Github:

http://willianantunes.blogspot.com.br/2014/04/datatables-com-vraptor.html

Abraços!

Criado 27 de setembro de 2013
Ultima resposta 22 de nov. de 2014
Respostas 6
Participantes 3