[Resolvido] TableModel demorando carregar dados

20 respostas
R

Boa tarde amigos tenho uma TableModel responsavel por passar para a view JTable os dados da entidade cidade onde tem uns 5 mil registros, a mesma esta demorando muito para carregar esses dados chega me média de 10 minutos alguém sabe o porque dessa demora toda ?

20 Respostas

D

Você esta usando paginação?

R

Não, estou mostrando os resultados todos na TableModel,
caso possa me ajudar amigo tbm uso o Towel ObjectTableModel

R

Testei usando paginação mas a demora em mostrar a lista na table ainda continua…

D

Faz o seguinte, cria o select trazendo ao poucos, eu uso como padrão trazer de 25 em 25, nisso você insere os botões anterior e próximo.

Se Precisar de mais ajuda só dizer…

Até mais…

V

Já usou um profiler para ver onde está o gargalo?

R
Olá ViniGodoy, não usei ainda profiler mais debuguei a aplicação e deu o seguinte erro,
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
	at sun.reflect.GeneratedConstructorAccessor5.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Unknown Source)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
	at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:381)
	at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305)
	at java.sql.DriverManager.getConnection(Unknown Source)
	at java.sql.DriverManager.getConnection(Unknown Source)
	at br.com.freedom.dao.ConexaoMySQL.getConexao(ConexaoMySQL.java:30)
	at br.com.freedom.dao.ConexaoMySQL.getPreparedStatement(ConexaoMySQL.java:39)
	at br.com.freedom.dao.Uf_dao.getUf(Uf_dao.java:18)
	at br.com.freedom.dao.Municipio_dao.populaMunicipio(Municipio_dao.java:52)
	at br.com.freedom.dao.Municipio_dao.listaMunicipios(Municipio_dao.java:38)
	at br.com.freedom.view.listas.ListaMunicipios.main(ListaMunicipios.java:25)
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection,  message from server: "Too many connections"
Informando que excedeu o numero de conexões mas eu estou fechando as conexões quando faço uma busca na base essa e minha classe Conexão em JDBC com MySQL
package br.com.freedom.dao;



import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

public class ConexaoMySQL {

    public  static String driver = "com.mysql.jdbc.Driver";//REFERENCIA DA CLASSE DRIVER MYSQL SERVER  
    public  static String url = "jdbc:mysql://localhost:3306/freedom?zeroDateTimeBehavior=convertToNull";//URL DO SERVIDOR DE BANCO DE DADOS 
    private String usuario = "root";//USUARIO DO BANCO DE DADOS
    private String senha = "mysqls3rv3r";//SENHA DO BANCO DE DADAS
    protected  PreparedStatement pstm;
    protected  Statement stm;
    protected  ResultSet rs;

    //conecta na base de dados
    public Connection getConexao() throws Exception {
        Class.forName(driver);
        Connection con = DriverManager.getConnection(url, usuario, senha);
        return con;
    }
    //metodo statement
    public Statement getStatement() throws Exception {
        return getConexao().createStatement();
    }
    //prepara o SQL a ser executado na base de dados
    public PreparedStatement getPreparedStatement(String SQL) throws Exception {
        return getConexao().prepareStatement(SQL);
    }
}
esse e meu model Uf
package br.com.freedom.model;

import java.io.Serializable;

import com.towel.el.annotation.Resolvable;

public class Uf implements Serializable {
	private static final long serialVersionUID = 1L;
	
	/*Atributos do objeto UF*/
	@Resolvable(colName="Id")
	private int 	id;
	@Resolvable(colName="Codigo")
	private String 	codigo;
	@Resolvable(colName="Sigla")
	private String 	sigla;
	@Resolvable(colName="Nome")
	private String 	nome;
	@Resolvable(colName="Ativo")
	private boolean ativo;
	
	/*Gets e Sets dos atributos do objeto UF*/
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getCodigo() {
		return codigo;
	}
	public void setCodigo(String codigo) {
		this.codigo = codigo;
	}
	public String getSigla() {
		return sigla;
	}
	public void setSigla(String sigla) {
		this.sigla = sigla;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public boolean isAtivo() {
		return ativo;
	}
	public void setAtivo(boolean status) {
		this.ativo = status;
	}
	
	
	
	
	

}
Meu model Municipio
package br.com.freedom.model;

import java.io.Serializable;

import com.towel.el.annotation.Resolvable;

public class Municipio implements Serializable{
	
	/*
	 * Atributos do obj Municipio
	 * */
	private static final long serialVersionUID = 1L;
	@Resolvable(colName="id")
	private int id;
	@Resolvable(colName="Codigo uf")
	private Uf iduf;
	@Resolvable(colName="Codigo do municipio")
	private String codigo;
	@Resolvable(colName="Nome")
	private String nome;
	@Resolvable(colName="Cep")
	private String cep;
	@Resolvable(colName="Ativo")
	private boolean ativo;
	
	/*
	 * Metodos Gets e Sets
	 * */
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Uf getIduf() {
		return iduf;
	}
	public void setIduf(Uf iduf) {
		this.iduf = iduf;
	}
	public String getCodigo() {
		return codigo;
	}
	public void setCodigo(String codigo) {
		this.codigo = codigo;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public String getCep() {
		return cep;
	}
	public void setCep(String cep) {
		this.cep = cep;
	}
	public boolean isAtivo() {
		return ativo;
	}
	public void setAtivo(boolean ativo) {
		this.ativo = ativo;
	}
	
	
	
	

}
Meu dao UfDAO
package br.com.freedom.dao;

import java.sql.ResultSet;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JOptionPane;

import br.com.freedom.model.Uf;

public class Uf_dao extends ConexaoMySQL{
	
	/*getUf retorna um Uf pelo Id informado*/
	public Uf getUf(int id)throws Exception{
		Uf lUf = new Uf();
		try {
			String SQL = "Select * From Uf Where Id = ?";
			pstm = getPreparedStatement(SQL);
			pstm.setInt(1, id);
			rs = pstm.executeQuery();
			if(rs.next()){
				lUf = populaUf(rs);
			}else{
				System.out.println("Não há uf com o código informado...\nCódigo informado $this->"+id);
			}
			pstm.close();
			return lUf;
		} catch (Exception e) {
			e.printStackTrace();
			// TODO: handle exception
			pstm.close();
			return lUf;
		}
	}
	
	/*
	 * Metodo List = o mesmo retorna uma lista de obj Uf
	 * */
	public List<Uf> listaUfs()throws Exception{
		Uf lUf = new Uf();
		List<Uf> lista = new LinkedList<Uf>();
		String SQL = "Select * from Uf Order By Nome";
		pstm = getPreparedStatement(SQL);
		rs = pstm.executeQuery();
			while(rs.next()){
				lUf = populaUf(rs);
				lista.add(lUf);
			}
		pstm.close();
		return lista;
	}
	
	/*Insert de um novo objeto Uf na entidade*/
	public boolean insertUf(Uf lUf)throws Exception{
		boolean resultado = false;
			String SQL = "Insert Into Uf(Codigo, Sigla, Nome, Ativo) Values(?,?,?,?)";
			pstm = getPreparedStatement(SQL);
			pstm.setString(1, lUf.getCodigo());
			pstm.setString(2, lUf.getSigla());
			pstm.setString(3,lUf.getNome());
			pstm.setBoolean(4, true);
			resultado =  pstm.execute();
			pstm.close();
			return resultado;		
	}
	
	public Uf populaUf(ResultSet rs)throws Exception{
		Uf lUf = new Uf();
			lUf.setId(rs.getInt(1));
			lUf.setCodigo(rs.getString(2));
			lUf.setSigla(rs.getString(3));
			lUf.setNome(rs.getString(4));
			lUf.setAtivo(rs.getBoolean(5));
			return lUf;		
	}
}
Meu dao MunicipioDAO
package br.com.freedom.dao;

import java.sql.ResultSet;
import java.util.LinkedList;
import java.util.List;

import br.com.freedom.model.Municipio;

public class Municipio_dao extends ConexaoMySQL{
	Uf_dao uf_dao = new Uf_dao();
	/*
	 * Metodo que retorna um Obj Municipio pelo Id - Chave Primaria
	 * */
	public Municipio getMunicipio(int id)throws Exception{
		Municipio lMunicipio = new Municipio();
		String SQL = "Select * From Municipio m Where m.Id = ?";
		pstm = getPreparedStatement(SQL);
		pstm.setInt(1, id);
		rs = pstm.executeQuery();
			if(rs.next()){
				lMunicipio = populaMunicipio(rs);
			}
		pstm.close();
		return lMunicipio;
	}
	
	/*
	 * Metodo List retorna uma lista de Obj Municipio
	 * */
	public List<Municipio> listaMunicipios()throws Exception{
		Municipio lMunicipio = new Municipio();
		List<Municipio> lista = new LinkedList<Municipio>();
		String SQL ="Select * from Municipio";
		//pstm.clearParameters();
		pstm = getPreparedStatement(SQL);
		rs = pstm.executeQuery();
			while(rs.next()){
				lMunicipio = populaMunicipio(rs);
				lista.add(lMunicipio);
				System.out.println(rs.getString(3));
			}
		pstm.close();
		return lista;
	}
	
	/*
	 * metodo populaMunicipio convert ResultSet para o Obj Municipio
	 * */
	public Municipio populaMunicipio(ResultSet rs)throws Exception{
		Municipio lMunicipio = new Municipio();
			lMunicipio.setId(rs.getInt(1));
			lMunicipio.setIduf(uf_dao.getUf(rs.getInt(2)));
			lMunicipio.setCodigo(rs.getString(3));
			lMunicipio.setNome(rs.getString(4));
			lMunicipio.setCep(rs.getString(5));
			lMunicipio.setAtivo(rs.getBoolean(6));
		return lMunicipio;
	}
}
Aqui é a view responsavel por mostrar os dados
package br.com.freedom.view.listas;

import java.util.LinkedList;
import java.util.List;

import test.model.Person;

import br.com.freedom.dao.Municipio_dao;
import br.com.freedom.model.Municipio;

import com.towel.collections.paginator.ListPaginator;
import com.towel.el.annotation.AnnotationResolver;
import com.towel.swing.table.ObjectTableModel;
import com.towel.swing.table.SelectTable;
import com.towel.swing.table.TableFilter;

public class ListaMunicipios {
	public static void main(String args[]){
		ObjectTableModel<Municipio> model = new ObjectTableModel<Municipio>(  
		        new AnnotationResolver(Municipio.class), "id,iduf.sigla:Sigla,codigo,nome,cep");  
		  
		model.setEditableDefault(true);  
		List<Municipio> lista = new LinkedList<Municipio>();
		 try {
			 lista  = new Municipio_dao().listaMunicipios();
		} catch (Exception e) {
			e.printStackTrace();
			// TODO: handle exception
		}
		  
		 SelectTable<Municipio> sel = new SelectTable<Municipio>(model,new ListPaginator<Municipio>(lista, 100)); 
		  
		  
		  
		new TableFilter(sel.getTable().getTableHeader(), sel.getModel());  
		  
		sel.showSelectTable(); 
	}

}
Essa e a primeira vez que me acontece isso se a aplicação não for em Debug ela nao informa os erros de números de conexões somente demora para mostrar os registros..
V
Resplandes:
Olá ViniGodoy, não usei ainda profiler

Então use:
http://java.dzone.com/articles/best-kept-secret-jdk-visualvm
http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/

Outra coisa, não estou vendo você fechar as conexões e nem os resultsets em local nenhum do seu código, só os statements. O jeito certo seria fazer assim:
public void enumerateBar() throws SQLException {
        Statement statement = null;
        ResultSet resultSet = null;
        Connection connection = getConnection();
        try {
            statement = connection.createStatement();
            resultSet = statement.executeQuery("SELECT * FROM Bar");
            // Use resultSet
        } finally {
            try {
                if (resultSet != null)
                    resultSet.close();
            } finally {
                try {
                    if (statement != null)
                        statement.close();
                } finally {
                    connection.close();
                }
            }
        }
    }

    private Connection getConnection() {
        return null;
    }

Para mais informações a respeito:
http://www.ibm.com/developerworks/java/library/j-jtp03216/index.html

Claro, se estiver usando o Java 7, pode usar o try with resources, que simplifica muito esse código.

R

ViniGodoy acabei de atualizar o driver do MySQL e o problema de conexões parou mas ai estou imprimindo os resultados da lista e como mostra ai no método listar da classe Municipio_dao.java mas ainda persiste demora em mostrar os 5 mil registros…
como faço para ver o gargalo da aplicação, seria um alto consumo de memoria ao executar a query ?

R

Opa ViniGodoy vou usar essa sua solução e posto aqui o resultado ok amigo, obrigado…

R

ViniGodoy caso possa me ajudar amigo fico grato eu estou usando o modelo que vc me passou mas mesmo assim continua a demora para exibiçao dos 5 mil registros, digo demora de 5 minutos agora para exibir os registros

package br.com.freedom.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;

import br.com.freedom.model.Municipio;

public class Municipio_dao extends ConexaoMySQL{
	Uf_dao uf_dao = new Uf_dao();
	/*
	 * Metodo que retorna um Obj Municipio pelo Id - Chave Primaria
	 * */
	public Municipio getMunicipio(int id)throws Exception{
		Statement statement = null;  
	    ResultSet resultSet = null;  
		Connection connection = getConexao();
		Municipio lMunicipio = new Municipio();
		try{
		String SQL = "Select * From Municipio m Where m.Id = "+id+"";
		resultSet = statement.executeQuery(SQL);
			if(resultSet.next()){
				lMunicipio = populaMunicipio(resultSet);
			}
			statement.close();
		}finally {  
	        try {  
	            if (resultSet != null)  
	                resultSet.close();  
	        } finally {  
	            try {  
	                if (statement != null)  
	                    statement.close();  
	            } finally {  
	                connection.close();  
	            }  
	        }  
	    }  
		return lMunicipio;
	}
	
	/*
	 * Metodo List retorna uma lista de Obj Municipio
	 * */
	public List<Municipio> listaMunicipios()throws Exception{
		Statement statement = null;  
	    ResultSet resultSet = null;  
		Connection connection = getConexao();
		Municipio lMunicipio = new Municipio();
		List<Municipio> lista = new LinkedList<Municipio>();
		try{
		String SQL ="Select * from Municipio";
		//pstm.clearParameters();
		resultSet = statement.executeQuery(SQL);
			while(resultSet.next()){
				lMunicipio = populaMunicipio(resultSet);
				lista.add(lMunicipio);
				System.out.println(resultSet.getInt(1));
			}
			statement.close();
		}finally {  
	        try {  
	            if (resultSet != null)  
	                resultSet.close();  
	        } finally {  
	            try {  
	                if (statement != null)  
	                    statement.close();  
	            } finally {  
	                connection.close();  
	            }  
	        }  
	    }  
		return lista;
	}
	
	/*
	 * metodo populaMunicipio convert ResultSet para o Obj Municipio
	 * */
	public Municipio populaMunicipio(ResultSet rs)throws Exception{
		Municipio lMunicipio = new Municipio();
			lMunicipio.setId(rs.getInt(1));
			lMunicipio.setIduf(uf_dao.getUf(rs.getInt(2)));
			lMunicipio.setCodigo(rs.getString(3));
			lMunicipio.setNome(rs.getString(4));
			lMunicipio.setCep(rs.getString(5));
			lMunicipio.setAtivo(rs.getBoolean(6));
		return lMunicipio;
	}
}

aqui a imagem da Java VisualVM

V

Usa o sampler que ele vai te mostrar qual método está demorando.

R

ViniGodoy agradeço pela força que esta me dando amigo, mais ainda nao tive resultados para saber o porque disso, o método que demora é o listar(); que executa a query
segue a img do sampler

R

Utilizando o profiler do netbeans com a JVisal VM o método ao qual mais esta em gargalo é o getConexao();
veja abaixo

V

Resolveu o problema? Se sim, posta a solução.

Você deve estar criando a conexão toda vez que chama esse método. Uma maneira simples de resolver seria criar a conexão uma vez só:

public class ConexaoMySQL {
   private Connection conn;
 
   public void getConexao() {
      if (conn == null) {
          //Cria a conexão e atribua a conn
      }
      return conn;
   }
}

Isso resolve para um trabalho de faculdade, mas não para um trabalho profissional. Se for profissional, use um Pool de conexões como o DBCP.

R

Isso mesmo ViniGodoy estou até vendo um modo de chama-la so uma vez agora vc me passou isso, e vou ver como usar o Pool de conexões como o DBCP para ficar de forma profissional como informado por você, mas vou postar sim a resolução agora amigo vlw obrigado…

V

E já valeu por você ter aprendido a usar o profiler. :slight_smile:

Isso aí vai te ajudar MUITO no futuro.

R

Opa e como já me ajudou esse inicio e muito, agora estou meio perdido em usar a API DBCP, não conhecia ela até o momento…
Agradeço por sua ajuda amigo…

M

O paginator (nem lembro direito como usa desculpe-me) do towel espera um Paginator, quando precisei implementar busca parcelada no banco de dados foi através dele, assim eu nunca precisava fazer um FULL SELECT no banco.

I

O paginator (nem lembro direito como usa desculpe-me) do towel espera um Paginator, quando precisei implementar busca parcelada no banco de dados foi através dele, assim eu nunca precisava fazer um FULL SELECT no banco.

Aliás, full select para milhares de linhas é temerário.Ninguém lê isso de uma vez, e sim 100,200,500(no máximo).

R

Resolvido usando pool de conexão indicado pelo ViniGodoy
segue o exemplo que postei no GUJ

http://www.guj.com.br/java/300753-modelo-de-classe-para-pool-de-conexao-java-swing

Criado 1 de junho de 2013
Ultima resposta 4 de jun. de 2013
Respostas 20
Participantes 5