Desempenho em programação OO com banco de Dados

3 respostas
ThiagoMM

Boa madrugada amigos.
Sou meio novatão em programação em JAVA e OO e estou enfrentando um probleminha no que diz respeito a performance.
Estou fazendo um programa para o meu estágio na faculdade que manipula um banco de dados MySQL. Para isso criei 3 classes: uma classe herdando do JFrame para os componentes gráficos, um gerenciador para fazer as operações CRUD no banco de dados e uma terceira classe que serve para armazenar endereço, nome de usuario e senha do banco MySQL.
No que diz respeito a FUNCIONAR, funciona (pelo menos a função que eu ja terminei), mas a aplicação está mais lerda do que lesma paralítica na subida, chegando a demorar 12 segundos para fazer uma simples consulta SELECT em uma tabela pequena (mais ou menos 6 registros com 6 campos cada) e inserir um registro nessa mesma tabela (6 campos).
Isso é normal? É comum demorar desse jeito? Antes de postar eu li em outros tópicos sobre performance do MySQL e havia um teste feito por @farnetaniPJ em [url]http://www.guj.com.br/java/158331-teste-de-desempenho-mysql-oracle-firebird-15-postgres[/url] dizendo que esse banco de dados demora por volta de 1 segundo para fazer 1000 operações de INSERT :shock:
Ficaria muito grato se algum dos amigos me desse uma dica sobre o que eu estou fazendo de errado, e prometo me lembrar deste dia e ajudar aos demais naquilo que eu souber.
Abraços

Este é o trecho do JFRAME que usa o objeto GereciadorFuncionario que faz as operações CRUD

//prossegue com o cadastro
       try
       {
                //verifica se o nome de usuário e senha informados pertencem a um administrador
                //caso o USER e SENHA informados sejam de um administrador, a funcção autenticaAdministrador retorna true
            
                GerenciadorFuncionario funcionario = new GerenciadorFuncionario();
                boolean loginAdmin = false;
                loginAdmin = funcionario.autenticaAdministrador(
                                        campoTextoAdmin.getText(), String.copyValueOf(campoSenhaAdmin.getPassword()));

                if (loginAdmin)
                {
                         funcionario.cadastraFuncionario(campoTextoNome.getText(), campoTextoRG.getText(), campoTextoNomeUsuario.getText(),
                                                String.copyValueOf(campoSenhaSenha1.getPassword()), jComboPrivilégioAcesso.getSelectedIndex());              //
                                   
                                   

                         JOptionPane.showMessageDialog(null, "Funcionário Cadastrado com Sucesso",
                                        "Operação Realizada", JOptionPane.INFORMATION_MESSAGE);
                  }
                  else
                  {
                           JOptionPane.showMessageDialog(null,
                                   "Senha ou nome de Usuários inválidos.\n"
                                 +"Verifique se você possui os direitos de acesso para esta operação.",
                                   "Erro de autenticação de Administrador", JOptionPane.ERROR_MESSAGE);
                   }
       }
       catch(ClassNotFoundException classE)
       {
                JOptionPane.showMessageDialog(null, classE.getMessage(),
                                    "Driver não encontrado", JOptionPane.ERROR_MESSAGE);
        }
        catch(SQLException sqlE)
        {
                 JOptionPane.showMessageDialog(null, sqlE.getMessage(),
                         "Erro de Banco de dados", JOptionPane.ERROR_MESSAGE);
         }

Este é o GerenciadorFuncionario que faz as operações CRUD

package br.unemat.estagio3.thiago;

import java.sql.ResultSet;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.SQLException;
import javax.swing.JOptionPane;

public class GerenciadorFuncionario
{
    private Connection con1;
    private Statement state1;
    private ResultSet result1;

    private Connection con2;
    private Statement state2;
    private ResultSet result2;


    //Método Construtor
    public GerenciadorFuncionario()throws SQLException, ClassNotFoundException
    {
        Class.forName(DBD.JDBC_DRIVER);

        //conecta-se aos bancos de dados
        con1 = DriverManager.getConnection(DBD.SGIA_DB, DBD.USER, DBD.PWD);        //DBD é a classe que contem URL, USUARIO E SENHA do MySql
        con2 = DriverManager.getConnection(DBD.SCASAA_DB,DBD.USER,DBD.PWD);

        //cria statement para trabalhar com os bancos de dados
        state1 = con1.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
        state2 = con2.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

    } // fim do construtor


     public boolean autenticaAdministrador(String nomeUsuario, String senha) throws SQLException
     {
        String query = String.format(
                "SELECT NOME_USUARIO, SENHA, PRIVILEGIO_ACESSO"
              + " FROM FUNCIONARIOS"
              + " WHERE NOME_USUARIO = \"%s\""
              + " AND SENHA = \"%s\"", nomeUsuario, senha);

        result2 = state2.executeQuery(query);
        while(result2.next())
        {
            if((result2.getString("NOME_USUARIO").equals(nomeUsuario))
                    && (result2.getString("SENHA").equals(senha))
                    && (result2.getInt("PRIVILEGIO_ACESSO")== 0))
                return true;
        }


        return false;

    }

  //recebe os dados do novo usuario e o cadastra no banco de dados
  public void cadastraFuncionario(String nome, String rg, String nomeUsuario,
                String senha, int priAcesso) throws SQLException
    {
        String slq = String.format(
                "INSERT INTO FUNCIONARIOS"
              + "(NOME_FUNCIONARIO, RG_FUNCIONARIO, NOME_USUARIO, SENHA, PRIVILEGIO_ACESSO)"
              + " VALUES (\"%s\", \"%s\", \"%s\", \"%s\", %d)",
              nome, rg, nomeUsuario, senha, priAcesso);
        state2.execute(slq);
    }


    //Este método encerra as conexões com o banco de dados
    public void close() throws SQLException
    {
        state1.close();
        state2.close();
        con1.close();
        con2.close();
    }

}

Esse aqui é só por questão de praticidade e portabilidade

package br.unemat.estagio3.thiago;

public class DBD {
    //Nomes e URLs dos Bancos de Dados MySql

    public static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    public static final String SGIA_DB = "jdbc:mysql://192.168.1.115:3306/sgia";
    public static final String SCASAA_DB = "jdbc:mysql://192.168.1.115:3306/scasaa";
    public static final String USER = "root";
    public static final String PWD = "estagio";


}

3 Respostas

otaviojava

está extremamente lerda, uma boa prática é fazer o DAO assim é mais fácil identificar o local do problema de desempenho.

paulo1911

Olá Thiago,

Realmente concordo com o amigo otaviojava.
Seu método está extremamente lento veja:

Pq vc cria 2 conexoes cn1 e cn2 e tb statments state 1 e state2?
A demora justifica no tempo de carregamento do drivermanager e do instancia da conexao, por isso usamos o padrão dao para que haja um pool de conexoes eque as mesmas sejam carregadas somente 1 vez quando starta a aplicação.

No seu método vc está criandoa conexao toda vez que for inserir e isso custa muito caro para o processamento. OK!
Pesquise sobre o padrão DAO.

Espero ter ajudado
Fallow

ThiagoMM

As conexões con1 e con2 e os statements 1 e 2 são porque acesso dois bancos de dados diferentes (ambos do MySQL) , mas ainda não fiz as funções que vão usar o outro banco.
Obrigado pela ajuda otaviojava e paulo1911… vou pesquisar sobre o DAO.

Abraços

Criado 19 de abril de 2011
Ultima resposta 19 de abr. de 2011
Respostas 3
Participantes 3