Problema com metodo de cadastro e fechar conexão com bd
23 respostas
LostSpirit
bom estou com um probleminha
eu consgio criar o primeiro usuario, mas depois não dar pra criar mais pq estou fechando a conexão alguém poderia me dar uma ideia de como resolver isso?
publicclassUsuarioDAO{privateConnectioncon;publicUsuarioDAO(){this.con=newConnectionFactory().getConnection();}publicbooleanadd(Usuariou){Stringsql="INSERT INTO usuario(login,senha,administrador) VALUES(?,?,?)";try{PreparedStatementstmt=con.prepareStatement(sql);stmt.setString(1,u.getLogin());stmt.setString(2,u.getSenha());stmt.setBoolean(3,u.isAdm());stmt.execute();stmt.close();con.close();returntrue;}catch(SQLExceptionex){Logger.getLogger(UsuarioDAO.class.getName()).log(Level.SEVERE,null,ex);returnfalse;}}
eu criei um construtor para que toda vez que se crie um UsuarioDAO ele tenha já conexão, se torna desnecessario?
Você não precisa ficar abrindo e fechando a conexão com o BD toda vez que for fazer alguma operação, a conexão com o BD você pode iniciar junto com sua aplicação e fechá-la quando sua aplicação se encerrar.
O que você deve ter o cuidado abrir e fechar sempre em todas as operações com o seu BD são as transações.
LostSpirit
como assim transações?
Jonathan_Medeiros
Toda operação de insert, update e delete são blocos de transações com o BD, para cada uma delas deve-se ter o cuidado de abrir e fechar a transação.
Exatamente! Eu, por exemplo, na classe que cria a conexão, nem crio um método para fechar a conexão. No meu método de criação, caso não exista conexão ele cria e pronto.
publicstaticConnectiongetConnection(){
try{
if(conexao==null){
Class.forName(DRIVER);conexao=DriverManager.getConnection(URL,USER,PASS);statement=conexao.createStatement();}
returnconexao;}catch(ClassNotFoundExceptionex){
JOptionPane.showMessageDialog(null,"Erro no driver jdbc!");ex.printStackTrace();returnnull;}catch(SQLExceptionex){
JOptionPane.showMessageDialog(null,"Erro na conexão com o banco de dados!");ex.printStackTrace();returnnull;}
}
Esse é o unico metodo que tem na minha classe. Dai na classe DAO eu so passo nos construtores se for necessário alguma informação para realizar algum método de transação com o BD. Talvez seja necessário ele receber uma ArrayList ou algo do tipo.
R
rlira1 like
Prezados bom dia, desculpe a pergunta mais é uma boa pratica abrir a conexão e só ao sair do sistema fechar?
Eu dou manutenção em um sistema que usa um banco MySql na Localweb e neste sistema ( é outra linguagem ) o trabalho é abrindo e fechando a conexão se a conexão ficar aberta de bobeira por alguns instantes… da BO
Jonathan_Medeiros1 like
Depende muito do contexto da aplicação ao qual ela se aplica, não é regra fazer isso, mas tem casos que se fazem necessário e casos que não, logo cada um implementa conforme sua necessidade.
LostSpirit
No caso seguindo a logica operações de transações seria interessante sempre fechar?
shodaime
Sim adote sempre esta boa pratica, pois isto pode gerar problemas futuros em sua aplicação.
Exemplo de uma classe de conexão que eu uso sempre
package br.com.appteste.connection;
import br.com.appteste.util.ConstantesBanco;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.swing.JOptionPane;
/**
*
*
*/
public class Conexao {
publicConnectioncon;staticStringhost=ConstantesBanco.HOST_LOCAL;staticStringdatabase=ConstantesBanco.DATABASE;staticStringusuario=ConstantesBanco.USUARIO;staticStringsenha=ConstantesBanco.SENHA;staticStringurl=ConstantesBanco.URL_LOCAL;publicConexao(){conectar();//chamando o metodo conectar}publicvoidconectar(){try{Class.forName("org.postgresql.Driver");System.out.println("Driver OK!!!");con=DriverManager.getConnection(url,usuario,senha);System.out.println("Conexão OK!!!");}catch(ClassNotFoundExceptionexc){System.out.println("Erro no driver, ClassNotFoundException "+exc.getMessage());}catch(SQLExceptionexc){System.out.println("Erro de conexao ,SQLException "+exc.getMessage());//JOptionPane.showMessageDialog(null, "Erro ao conectar no Banco de Dados! \n"+exc.getMessage(),"Erro ao Conectar no Banco de Dados",JOptionPane.ERROR_MESSAGE);}}publicvoidfecharConexao(){try{con.close();// fechando a conexaoSystem.out.println("CONEXÃO FECHADA!");}catch(SQLExceptionexc){System.out.println(exc.getMessage());//JOptionPane.showMessageDialog(null, "Erro ao fechar Conexão no Banco de Dados! \n"+exc.getMessage(),"Erro ao Fechar Banco de Dados",JOptionPane.ERROR_MESSAGE);}}
}
LostSpirit
man me tira só uma dúvida em relação a url
“jdbc:mysql://localhost:3306/xxx”
teria como por algo menor do q isso? ou tem que ser exatamente assim…
shodaime
seria isto mesmo
Jonathan_Medeiros
As transações sim, a conexão com o BD somente se você julgar necessário!
LostSpirit
Ou seja um ex válido o login no método de validação onde tem a transação select eu fecharia e ao fazer login eu abriria novamente ?
Ou fechar apenas o preparedstatment?
Jonathan_Medeiros1 like
Consultas não são transacionais, pois as mesmas não alteram o estado atual dos dados.
Somente instruções de inserção, alteração e deleção são transacionais, pois as mesmas modificam o estado atual dos dados.
Sobre seu código você pode fechar somente o PreparedStatement.
LostSpirit
Fechando somente o prepared não irá fechar a conexão não é?
Caso eu faça um insert fechar apenas o prepared iria resolver ?
Jonathan_Medeiros
Sim, são objetos distintos, fechar o pst não influencia na conexão.
Isso aqui ficou um pouco confuso, resolver o que exatamente?
LostSpirit
Sobre abrir transacoes, fechar só com preparares já resolve? Ou é necessário fechar a conexão?
Jonathan_Medeiros1 like
A conexão não precisa ser fechada, a não ser que você queira manter esse padrão de abrir e fechar a conexão sempre, mas tem que ter o cuidado e a atenção para garantir que a conexão esteja ativa sempre que for fazer qualquer operação relacionada com o BD, como um CRUD por exemplo.
A parte de transações vai um pouco além do que foi comentado aqui, elas incidem diretamente ao uso de commit e rollback visando sempre as propriedades ACID.
O PreparedStatement é só uma classe que nos fornece meios de fazer esse controle, mas é preciso todo o entendimento real por trás disso tudo para que não se faça algo errado.
Ou seja só o fato de dar o close no objeto não diz respeito a transação, pegou mais ou menos a ideia?
LostSpirit
Vou dar uma procurada sobre commit e rollback, peguei sim, vou dar uma lida para tentar fazer o Max possível no padrão, vlw man.
LostSpirit
Se você poder me dar um exemplo de como eu usaria o commit e rollback no Java para tentar compreender, tava dando uma olhada e falam que tem que comitar todas as transações de uma vez kk, o problema é que tenho muitos métodos, se você poder ajudar com algum exemplo com mais de um método .
LostSpirit
Dando uma aprofundada percebi que nao necessariamente necessita commitar tudo de uma única vez e sim o máximo possível,
Poderia me corrigir se eu estiver errado?
Nesse caso não seria necessário commitar o select
E se eu fizer um select e depois um update eu teria que executar o select normalmente e depois commitar o update ?
Ou no caso fazer um método isolado para o update e chamar no método de insert?
Estou na lógica certa?
Ficaria grato se poder me dar um exemplo de commite utilizando mais de um método.
Jonathan_Medeiros1 like
Commit se aplica sempre à uma transação completa, nunca parcial.
Não entendi sua pergunta, select é consulta, e consulta não envolve o âmbito de transações.
Está muito confuso, porquê fazer um método de update em um método de insert?!
Um exemplo de transação que você utilizaria múltiplos métodos, seria uma venda por exemplo.
Início da transação
Insere a venda
Insere os ítens da venda
Insere a baixa do estoque
Insere o contas a receber
Insere o movimento de caixa
Fim da transação
Se todas etapas foram concluídas com sucesso então é aplicado o commit na transação, caso contrário alguma etapa apresente falha então é aplicado o rollback.
LostSpirit
Pq eu tenho um campo no usuário , como ativo, boolean para verificar se ele está online,
Seria um alter table na verdd, falando nisso você poderia me ajudar se tem como chamar um método ao fechar o app, (ex se fechar instância pelo gerenciador chamasse esse método tambrm, para alterar o campo para 0)
Eu teria que trabalhar com rotina no caso ?