Problema Com JDBC

4 respostas
L

Boa tarde a todos.

Meu nome é Douglas, sou aluno do 3º semestre de BSI, e trabalho com suporte a algum tempo; Atualmente estou tentando aprender e melhorar mais meus conhecimentos na área de desenvolvimento, mais especificamente JAVA. Já possuo alguma experiência com Delphi, e POO, mas no entando estou apenas "Iniciando" no caminho do Java.

Pois bem, aqui está uma breve descrição do que venho fazendo:

Recentemente criei, utilizando JDK 1.5.0 update 9 e NetBeans 5.5 duas classes: A classe TesteJDBC e a classe InterfaceGrafica. A Classe TesteJDBC funciona perfeitamente, e apresenta as seguintes funcionalidades:
- Carrega o Driver ponte JDBC-ODBC e se conecta a um Banco de Dados Access chamado Cds, que está localizado na pasta do projeto; Todas as configurações de ODBC do windows já estão ok e o acesso ocorre perfeitamente, apartir do método Conecta();
- Possui um método CriaTabelas que pode ser chamado para gerar uma tabela chamada Cds com dois campos (Titulo e NCopias) o qual utilizei apenas uma vez a título de aprendizado, não sendo o mesmo utilizado em minha aplicação já que a tabela já está criada;
- Possui um método InsereDados, trabalhando com Prepared Statement, Recebendo dois valores (String e Int) para repassar como um novo registro da tabela;

No mesmo pacote possuo a classe InterfaceGrafica; Nada mais é que uma classe com um botão e duas JTextBoxes para receber o valor do Titulo e do numero de copias para que possa ser repassado para o método InsereDados cadastrar na tabela, no evento de clique do botão.

Eis o problema:

Como o método InsereDados é um método da classe TesteJDBC e eu não posso declará-lo como static pois o prepared statement não permite, como faço para chamá-lo ao clicar o botão?
Pois para chamar o mesmo no actionEvent do botão eu irei necessitar de chamá-lo apartir do nomeDaInstancia.Metodo, ou seja, algo como novo.InsereDados, necessitando de instanciar a mesma dentro do actionEvent do botão. Se eu fizer isso funciona, mas TODA vez que eu clicar no botão e executar um cadastro, a classe será novamente instanciada..

Realmente não sei a estrutura correta para que eu possa fazer o correto: Instanciar o objeto e apenas chamar seu método para inserir os dados obtidos ao clicar o botão da InterfaceGrafica, apartir das caixas de texto.

Seguem os códigos fonte:

TesteJDBC.java:

package bancodedados;
import java.sql.*;
import javax.swing.JOptionPane;

public class TesteJDBC{
    String url= "jdbc:odbc:Cds";
    Connection con;

    public Connection Conecta(){
        try
            {
                System.out.println("Iniciando a conexão com o BD...");
                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
                con = DriverManager.getConnection(url,"","");
                System.out.println("Banco de Dados Ok e Pronto...");
                return con;
            }
        catch(ClassNotFoundException cnf)
            {
                System.out.println("Houve uma ClassNotFoundException: "+cnf);
                return null;
            }
        catch(SQLException sql)
            {
                System.out.println("Houve uma SQLException: "+sql);
                return null;
            }
    }

    

        public void CriaTabelas(){
            try {
                Statement st = con.createStatement( );
                st.executeUpdate("create table Cds(Titulo varchar(32),NCopias integer);");
                System.out.println("Tabela Criada com Sucesso!");
                st.close();
                }
            catch(SQLException sql)
                {
                System.out.println("Erro! "+sql);
                }
        }

        public void InsereDados(String a, int b){
            try {
                PreparedStatement st2 = con.prepareStatement("insert into Cds values(?,?)" );
                st2.setString(1,a);
                st2.setInt(2,b);
                st2.execute();
                st2.close();
                con.close();
                System.out.println("Dados Adicionados Com Sucesso!");
            }
            catch(SQLException sql)
            {
                System.out.println("Erro! "+sql);
            }
        }

      }

InterfaceGrafica.java

package bancodedados;

import bancodedados.TesteJDBC;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class InterfaceGrafica extends JFrame implements ActionListener
{
    JButton botao;
    JPanel panel;
    JTextField texto,texto2;
    String a,intSemConverter;
    int intConvertido;
   
    
    public InterfaceGrafica() {
         super("BancoDeDados 1.0");
     }
     
     public void criaJanela()
     {        
         texto = new JTextField("");
         texto2 = new JTextField("");
         panel = new JPanel();
         panel.setLayout(new GridLayout(2, 1));
                 
         botao = new JButton("Clique para Cadastrar!");
         botao.addActionListener(this);
         
         panel.add(texto);
         panel.add(botao);
         panel.add(texto2);
         
         getContentPane().add(panel, BorderLayout.CENTER);
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         
         pack();
         setVisible(true);        
     }
     
         
     public void actionPerformed(ActionEvent event)
     {
         TesteJDBC novo = new TesteJDBC();
         novo.Conecta();
 
         
         a = texto.getText();
         intSemConverter = texto2.getText();
         intConvertido = Integer.parseInt(intSemConverter);
         
         novo.InsereDados(a,intConvertido);
         
               
     }
     
     public static void main(String args[])
     {
         
         InterfaceGrafica ex2 = new InterfaceGrafica();
         ex2.criaJanela();
         
         
     }
 }

Repare que deste modo FUNCIONA, mas cria uma instancia de TesteJDBC a todo clique do botão. Colocar um If com um contador para evitar uma segunda execução (If contador == 0) {
faz instancia
contador++;
}

nao funciona, pois volta o problema de não reconhecer o novo.InsereDados, como se a instancia nao estivesse sendo criada.

Creio que tenha sido um pouco confuso.. e acho que a maneira que estou utilizando para trabalhar com o cadastramento deve estar incorreto, portanto agradeço qualquer ajuda. Realmente não sei como vou colocar isso pra funcionar sem redundâncias ^^

Obrigado a todos,

Douglas Vargas

Ps. Agradecimento ao portal da GUJ e pelo tutorial sobre Swing, no qual tem base a parte gráfica da minha aplicação. A maior parte do código relativo ao Swing foi baseado nesse tutorial, então muito obrigado :)

4 Respostas

Pedrosa

Esse tutorial pode ser util para você:

http://www.guj.com.br/java.tutorial.artigo.155.1.guj

L

Hum… muito obrigado!
Estou lendo aqui… mas me pareceu bem interessante. Basicamente esse PicoContainer vai possibilitar essa minha interação de métodos de classes diferentes sem a instanciação toda vez que eu precisar utilizá-los, certo?
Vou tentar fazer aqui. Qualquer duvida eu falo.

Muito obrigado de novo!

L

Weeeeeeeeee!
Acho q consegui!

Ainda tenho uma duvidazinha, mas vamos ao que interessa:
(Ainda não sei se está certo eheheheh) ^^

Segue o novo código fonte do InterfaceGrafica.java:

package bancodedados;

import bancodedados.TesteJDBC;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.defaults.DefaultPicoContainer;

public class InterfaceGrafica extends JFrame implements ActionListener
{
    JLabel label1,label2;
    JButton botao;
    JPanel panel;
    JTextField texto,texto2;
    String a,intSemConverter;
    int intConvertido;
    MutablePicoContainer pico = new DefaultPicoContainer();

    
    public InterfaceGrafica() {
        super("BancoDeDados 1.0");
     }
     
     public void criaJanelaEContainer()
     {        
         label1 = new JLabel("Titulo:");
         label2 = new JLabel("Nº Cópias");
         texto = new JTextField("");
         texto2 = new JTextField("");
         panel = new JPanel();
         panel.setLayout(new GridLayout(3,2));
                 
         botao = new JButton("Clique para Cadastrar!");
         botao.addActionListener(this);
         
         panel.add(label1);
         panel.add(texto);
         panel.add(label2);
         panel.add(texto2);
         panel.add(botao);

         
         getContentPane().add(panel, BorderLayout.CENTER);
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         
         pack();
         setVisible(true);        
     
         pico.registerComponentImplementation(TesteJDBC.class);
         
         
          
        
         

     }
     
         
     public void actionPerformed(ActionEvent event)
     {
         TesteJDBC teste = (TesteJDBC) pico.getComponentInstance(TesteJDBC.class);
         a = texto.getText();
         intSemConverter = texto2.getText();
         intConvertido = Integer.parseInt(intSemConverter);
         
         teste.Conecta();
         teste.InsereDados(a,intConvertido);
       
         
               
     }
     
     public static void main(String args[])
     {
         
         InterfaceGrafica ex2 = new InterfaceGrafica();
         ex2.criaJanelaEContainer();
         
         
     }
 }

É isso mesmo? Ainda não sei se está correto.

Tipo, se eu entendi bem, no trecho de código

pico.registerComponentImplementation(TesteJDBC.class);
eu registrei a classe TesteJDBC.class como uma classe que eu irei instanciar utilizando o PicoContainer; e aqui
TesteJDBC teste = (TesteJDBC) pico.getComponentInstance(TesteJDBC.class);
Eu requisitei uma instancia da mesma através do picoContainer. E toda vez que eu clicar no botão esse trecho de código não irá criar uma nova instancia da classe TesteJDBC, mas sim apenas requisitar uma instância da mesma.. que o pico ja criou e vai reutilizar.. certo?

Ainda restou essa dúvida ^^

Abraços, e muito obrigado novamente!

Douglas Vargas

L

Mais uma coisa:
Ouvi falar que o padrão de projeto (Design Pattern) MVC - Model View Controller também serve para resolver esse tipo de problema.
Estou pesquisando pra saber como funciona… agradeço se alguem souber me passar um exemplo de como eu aplicaria o MVC a minha aplicação. Já sei que eu teria de dividir as tarefas, de modo que a interface gráfica chame um controlador que por sua vez iria chamar a minha classe responsável pela conexão com o banco. Mas realmente ainda não descobri como implementar isso.

Se alguem tiver alguma dica, agradeço!

Douglas Vargas

Criado 21 de novembro de 2006
Ultima resposta 22 de nov. de 2006
Respostas 4
Participantes 2