Ajuda no metodo de conexão JDBC

13 respostas
C

Pessoal, preciso de uma luz só pra me mostrar onde está o erro nessa conexão.

1 tenho minha classe de interface.

package dao;

import classes.Cliente;
import java.util.List;

/**
 *
 * @author Administrador
 */
public interface IClienteDao {

    public void cadastrarCliente( Cliente c);
    public void deletarCliente();
    public void atualizarCliente();
    public List listarCliente();

}
classe de conexão:
public class Connection{

public static Connection getConnection() throws ClassNotFoundException, SQLException {
   Class.forName("com.mysql.jdbc.Driver");
		String URL = "JDBC:MYSQL://localhost:3306/quitanda";
		Connection conn = (Connection) DriverManager.getConnection(URL, "root", "people");
		return conn;
}

aqui é onde está o erro: conn.prepareStatement(sql);( está pedindo para criar um metodo prepareStatement em conn.connection.

public class ClienteDaoMysql implements  IClienteDao {

   private Connection conn;

   public ClienteDaoMysql(Connection conn){
		this.conn = conn;
	}
   
    public void cadastrarCliente( Cliente c) {
        try {
   
            String sql = "insert into cliente(Nome,CPF) values(?,?)";
            //Preparando a Statement
            PreparedStatement stmt = conn.prepareStatement(sql);
            stmt.setString(1, c.getNome());
            stmt.setString(2, c.getCpf());
            stmt.execute();
            stmt.close();
     
    }

como corrigir?

13 Respostas

rmendes08

Sem a stack trace do erro fica difícil, mas provavelmente o erro é nessa linha:

stmt.execute();

que deve ser trocada por:

stmt.executeUpdate();
Nicolas_Fernandes

Existem várias classes chamadas Connection. Uma delas é a classe Connection do pacote Corba. Confira se o seu import para esta classe connection é o:

Abraços!

C

bom adicionei o import que o nicolas citou e o erro sumiu.
e tbm fiz a alteração para executeUpdate();

ai tentei fazer o teste abaixo.

public static void main(String[] args) {

        ClienteDaoMysql clienteDao = new ClienteDaoMysql();
        Cliente cliente = new Cliente();

        cliente.setNome("caio");
        cliente.setCpf("[telefone removido]");
        clienteDao.cadastrarCliente(cliente);

        System.out.println("Dados cadastrados");
}
}

ele me retorna esse erro:

run:
Exception in thread "main" java.lang.NullPointerException
        at dao.Mysql.ClienteDaoMysql.cadastrarCliente(ClienteDaoMysql.java:39)
        at quitanda.Main.main(Main.java:27)
Java Result: 1
CONSTRUÍDO COM SUCESSO (tempo total: 0 segundos)

indicando essa linha como erro:

PreparedStatement stmt = conn.prepareStatement(sql);
rmendes08

você esqueceu de passar a conexão para o DAO.

C

rmendes, desculpa a ignorância,
mas quando eu uso:

public class ClienteDaoMysql implements  IClienteDao {  
  
   private Connection conn;  
  
   public ClienteDaoMysql(Connection conn){  
        this.conn = conn;  
    }

Já não estou passando a conexão??? se não como faria isso?

obrigado pela atenção.

Nicolas_Fernandes
CaioNascimento:
rmendes, desculpa a ignorância, mas quando eu uso:
public class ClienteDaoMysql implements  IClienteDao {  
  
   private Connection conn;  
  
   public ClienteDaoMysql(Connection conn){  
        this.conn = conn;  
    }

Já não estou passando a conexão??? se não como faria isso?

obrigado pela atenção.


Confira se a seu objeto de conexão está recebendo uma conexão válida, e não null.
Outra coisa: executeUpdate() só para updates. Caso contrário, use o método execute.

luxu

vc está chamando Connection mas ele vem sem nada, tenta assim:

public class ClienteDaoMysql implements  IClienteDao {

   private Connection conn;

   public ClienteDaoMysql(Connection conn){
		this.conn = conn;
	}
   
    public void cadastrarCliente( Cliente c) {
        try {
	        conn = Connection.getConnection();
	        String sql = "insert into cliente(Nome,CPF) values(?,?)";
            //Preparando a Statement
            PreparedStatement stmt = conn.prepareStatement(sql);
            stmt.setString(1, c.getNome());
            stmt.setString(2, c.getCpf());
            stmt.execute();
            stmt.close();
     
    }
leonhard32
CaioNascimento:
bom adicionei o import que o nicolas citou e o erro sumiu. e tbm fiz a alteração para executeUpdate();

ai tentei fazer o teste abaixo.

public static void main(String[] args) {

        ClienteDaoMysql clienteDao = new ClienteDaoMysql();
        Cliente cliente = new Cliente();

        cliente.setNome("caio");
        cliente.setCpf("[telefone removido]");
        clienteDao.cadastrarCliente(cliente);

        System.out.println("Dados cadastrados");
}
}

ele me retorna esse erro:

run:
Exception in thread "main" java.lang.NullPointerException
        at dao.Mysql.ClienteDaoMysql.cadastrarCliente(ClienteDaoMysql.java:39)
        at quitanda.Main.main(Main.java:27)
Java Result: 1
CONSTRUÍDO COM SUCESSO (tempo total: 0 segundos)

indicando essa linha como erro:

PreparedStatement stmt = conn.prepareStatement(sql);

Cara, quando você instancia o Objeto ClienteDaoMysql, você não passa uma Connection
Porém, você ja tinha criado o método "getConnection()"... das duas uma, você dá um "getConnection()", para passar a Connection na instanciação da classe ClienteDaoMysql
ou
Instancia uma Connection dentro do construtor da ClienteDaoMysql

leonhard32

Faça algo como:

public class ClienteDaoMysql implements  IClienteDao {
    
   private Connection conn;
    
   public ClienteDaoMysql(){
        this.conn = Connection.getConnection();
}
Nicolas_Fernandes
leonhard32:
Faça algo como:
public class ClienteDaoMysql implements  IClienteDao {
    
   private Connection conn;
    
   public ClienteDaoMysql(){
        this.conn = Connection.getConnection();
}

Leon, não funciona desse modo se ele está fazendo injeção de dependências. Quando acontece essa situação, você passa os objetos necessários via construtor da classe.
Para que fique de acordo com o que ele quer, deve-se passar a conexão pelo construtor da classe DAO.

Caio, seu código DAO está assim:
public class ClienteDaoMysql implements  IClienteDao {  
  
    private Connection conn;  
  
    public ClienteDaoMysql(Connection conn){  
         this.conn = conn;  
    } 
    //...
}
e seu código Main está assim:
public static void main(String[] args) {  
      
    ClienteDaoMysql clienteDao = new ClienteDaoMysql();  
    Cliente cliente = new Cliente();  
      
    cliente.setNome("caio");  
    cliente.setCpf("[telefone removido]");  
    clienteDao.cadastrarCliente(cliente);  
      
    System.out.println("Dados cadastrados");  
}

No Main, onde você está passando o objeto de conexão para a sua classe DAO?
Se você está trabalhando com injeção de dependências, deveria ser assim:

public static void main(String[] args) {  
      
    // Cria seu objeto Connection aqui...
    Connection connection = SuaClasseDeConnection.getConnection();

    // E passa ele para o construtor da classe DAO aqui!
    ClienteDaoMysql clienteDao = new ClienteDaoMysql(connection);  
    Cliente cliente = new Cliente();  
      
    cliente.setNome("caio");  
    cliente.setCpf("[telefone removido]");  
    clienteDao.cadastrarCliente(cliente);  
      
    System.out.println("Dados cadastrados");  
}

Algumas considerações:

1. Mude o nome da sua classe que fabrica conexões de Connection para qualquer outro nome. Já existem objetos Connection de outros lugares, e aí fica muito confuso. Algo como ConnectionFactory ou ConnectionHelper cairia muito bem como nome da classe.

Abraços!

leonhard32

Sim, mas esta forma de implementação não há beneficios, levando em conta que cada nova chamada do método, ele precisará passar novamente uma Connection…

Além das suas dicas, do nome de classe, eu sugiro que o CaioNascimento não utilize a chamada de suas classes DAO dessa forma, mas sim que divida melhor as camadas do sistema…

Faça as chamadas de métodos diretamente na classe MODELO, a classe modelo terá relação com os métodos da classe DAO…

Qualquer dúvida eu posso postar um exemplo…

Abs

romarcio

A diferença entre o método execute() e executeUpdate() é apenas o tipo de retorno.

Nicolas_Fernandes
leonhard32:
Nicolas Fernandes:

Leon, não funciona desse modo se ele está fazendo injeção de dependências. Quando acontece essa situação, você passa os objetos necessários via construtor da classe.
Para que fique de acordo com o que ele quer, deve-se passar a conexão pelo construtor da classe DAO.

Sim, mas esta forma de implementação não há beneficios, levando em conta que cada nova chamada do método, ele precisará passar novamente uma Connection...

Vejo claramente o padrão de injeção de dependências. E se o cara quiser usar somente uma conexão para realizar várias operações de uma vez só em várias entidades do banco de dados? Vai abrir e fechar conexão toda hora que for requisitar dados do DB?
E se ele quiser manter uma conexão aberta somente na Sessão para o usuário e repassá-la quando precisar realizar qualquer operação de consulta no DB? Não é muito mais válido? Onde você não vê benefícios aqui?

Sou muito mais adepto da Injeção de Dependências em uma situação do tipo:
public class Main {

    public static void main(String[] args) {

        // Tudo isso usando uma única conexão para este usuário
        // a fim de não sobrecarregar o número de conexões no DB.
        Connection minhaConexao = ServicosConnection.getConnection();
        ClasseDeServicos1 servicos1 = new ClasseDeServicos1(minhaConexao);
        ClasseDeServicos2 servicos2 = new ClasseDeServicos2(minhaConexao);
        ClasseDeServicos3 servicos3 = new ClasseDeServicos3(minhaConexao);
        ClasseDeServicos4 servicos4 = new ClasseDeServicos4(minhaConexao);

        servicos1.atualizaAlgumaCoisa();
        servicos2.consultaEmUmaTabela();
        servicos3.insereDadosEmUmaNovaTabela();
        servicos4.atualizaMaisAlgumaCoisa();

        ServicosConnection.concluirOperacoes(minhaConexao);
    }
}
e...
public class ClasseDeServicos1 {

    private Connection conexaoQueReceboPeloConstrutor;
    public ClasseDeServicos1(Connection conexaoQueReceboPeloConstrutor) {
        this.conexaoQueReceboPeloConstrutor = conexaoQueReceboPeloConstrutor;
    }

    public void atualizaAlgumaCoisa() {
        //Faz alguma operação usando a conexão que foi repassada à instância da classe.
    }
}

Do que, a cada vez que eu criar uma instância da classe ou requisitar uma operação no DB, seja necessária uma nova conexão, como por exemplo:

public class Main {

    public static void main(String[] args) {

        ClasseDeServicos1 servicos1 = new ClasseDeServicos1();
        ClasseDeServicos2 servicos2 = new ClasseDeServicos2();
        ClasseDeServicos3 servicos3 = new ClasseDeServicos3();
        ClasseDeServicos4 servicos4 = new ClasseDeServicos4();

        servicos1.atualizaAlgumaCoisa();
        servicos2.consultaEmUmaTabela();
        servicos3.insereDadosEmUmaNovaTabela();
        servicos4.atualizaMaisAlgumaCoisa();
    }
}
e...
public class ClasseDeServicos1 {

    public ClasseDeServicos1() { }

    public void atualizaAlgumaCoisa() {
        
        // busca uma nova conexão.
        Connection minhaConexao = ServicosConnection.getConnection();
        // atualiza alguma coisa...
    }
}

public class ClasseDeServicos2 {

    public ClasseDeServicos2() { }

    public void consultaEmUmaTabela() {
        
        // busca outra nova conexão. Se não der commit na conexão no método de cima, 
        // perde o que tinha feito nele.
        Connection minhaConexao = ServicosConnection.getConnection();
        // consulta em uma tabela...
    }
}
leonhard32:
Além das suas dicas, do nome de classe, eu sugiro que o CaioNascimento não utilize a chamada de suas classes DAO dessa forma, mas sim que divida melhor as camadas do sistema...

Faça as chamadas de métodos diretamente na classe MODELO, a classe modelo terá relação com os métodos da classe DAO...

Qualquer dúvida eu posso postar um exemplo...

Abs

Exato, o Leon tem razão, Caio. Defina uma arquitetura para o seu sistema e aplique-a nesse contexto. Para começar, porque não definir uma arquitetura MVC e trabalhá-la aí? O que eu fiz foi um exemplo baseado no que você tinha feito para entender como resolver seu problema, mas também sou adepto ao uso de uma arquitetura aí!

Abraços, fiquem com Deus!

Criado 20 de agosto de 2011
Ultima resposta 21 de ago. de 2011
Respostas 13
Participantes 6