Problema com metodo de cadastro e fechar conexão com bd

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?

public class UsuarioDAO {

    
    private Connection con;

    public UsuarioDAO() {
        this.con = new ConnectionFactory().getConnection();
    }

    public boolean add(Usuario u) {
        String sql = "INSERT INTO usuario(login,senha,administrador) VALUES(?,?,?)";
        try {
            PreparedStatement stmt = con.prepareStatement(sql);
            stmt.setString(1, u.getLogin());
            stmt.setString(2, u.getSenha());
            stmt.setBoolean(3, u.isAdm());
            stmt.execute();
            stmt.close();
            con.close();
            return true;
        } catch (SQLException ex) {
            Logger.getLogger(UsuarioDAO.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

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.

1 curtida

como assim transações?

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.

Segue exemplos:
https://www.mkyong.com/jdbc/jdbc-transaction-example/
https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html

vlw vou dar uma olhada.

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.

public static Connection getConnection() {
        try {
            if (conexao == null) {

                Class.forName(DRIVER);
                conexao = DriverManager.getConnection(URL,USER,PASS);
                statement = conexao.createStatement();
            }
            return conexao;

        } catch (ClassNotFoundException ex) {
            JOptionPane.showMessageDialog(null, "Erro no driver jdbc!");
            ex.printStackTrace();
            return null;
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Erro na conexão com o banco de dados!");
            ex.printStackTrace();
            return null;
        }
    }

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.

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

1 curtida

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.

1 curtida

No caso seguindo a logica operações de transações seria interessante sempre fechar?

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 {

public Connection con;

static String host = ConstantesBanco.HOST_LOCAL;
static String database = ConstantesBanco.DATABASE;
static String usuario = ConstantesBanco.USUARIO;
static String senha = ConstantesBanco.SENHA;
static String url = ConstantesBanco.URL_LOCAL;


public Conexao() {

    conectar(); //chamando o metodo conectar

}

public void conectar() {
    try {
        Class.forName("org.postgresql.Driver");
        System.out.println("Driver OK!!!");

        con = DriverManager.getConnection(url, usuario, senha);
        System.out.println("Conexão OK!!!");

    } catch (ClassNotFoundException exc) {
       
        System.out.println("Erro no driver, ClassNotFoundException " + exc.getMessage());

    } catch (SQLException exc) {
        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);
    }
}

public void fecharConexao() {
    try {
        con.close(); // fechando a conexao
        System.out.println("CONEXÃO FECHADA!");
    } catch (SQLException exc) {
        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);
    }
}

}

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…

seria isto mesmo

As transações sim, a conexão com o BD somente se você julgar necessário!

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?

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.

1 curtida

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 ?

Sim, são objetos distintos, fechar o pst não influencia na conexão.

Isso aqui ficou um pouco confuso, resolver o que exatamente?

Sobre abrir transacoes, fechar só com preparares já resolve? Ou é necessário fechar a conexão?

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?

1 curtida

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.