Conexão BD!

35 respostas
paulinhohd

E ae galera?

Seguinte:

Consigo fazer a conexão com um BD no Acess usando JDBC:ODBC facilmente, indicando o caminho, pois o banco está local na máquina, porém eu queria um auxílio, se é melhor eu abrir e fechar a conexão sempre que for acessar ou se tem como eu abrir só uma vez e realizar as consultas normalmente.

Detalhe, já tentei colocar em classe separada a conexão, porém daí, quando tento fazer o SELECT em outras classes ele não encontra as váriáveis, sendo que já colquei até como globais.

Se alguém puder ajudar!

Valeu! 8)

35 Respostas

jmedeiros

Sua aplicação vai ficar bem mais rápida se vc deixar a conexão sempre aberta e só fechar quando o usuário sair.

Acho que no seu caso será necessário criar uma pool de conexões, ou seja uma classe com todas os metodos de conexão que você precisa.

exemplo:

classe conexao{

-fazConexao();

-fechaConexao();

-pegaConexao();

}

Quando vc for utilizar um comando SELECT por exemplo em outra classe vc chama o metodo necessario no seu pool de conexao.

Da uma pesquisada no fórum tem muita coisa sobre isso.

Espero ter ajudado.

fbanin

sou novo aqui, mas vou tentar ajudar…

Na classe de conexão vc cria a variavel CONNECTION como static, e faz uma verificação antes de criar a conexão se ela é nula, se for, vc cria a conexão, caso contrário passa direto, pois a conexão já esta feita.

Agora qto aos selects, fica melhor vc fazer a conexão e criar as resultsets na outra classe, não a da conexão…

Estou fazendo dessa forma, eu criei uma classe de conexão como expliquei acima… e criei uma outra classe igual a minha tabela do Access, nessa classe eu dou os selects, inserts, updates e deletes que eu preciso, tudo isso usando a conexão da classe de conexão… deu certo… agora só preciso melhorar e passar para meu futuro sistema…

Abraços

paulinhohd

Fabiano, eu já tentei fazer isso, porém, eu coloquei a conexão no Init mesmo, daí mesmo dentro do init, não conseguia fazer ele aceitar as variáveis.

Vc tem algum tutorial bom ou algum trecho de código-exemplo para me fornecer?

Mesmo assim Valeu! 8)

paulinhohd

jmedeiros:
Acho que no seu caso será necessário criar uma pool de conexões, ou seja uma classe com todas os metodos de conexão que você precisa.

exemplo:

classe conexao{

-fazConexao();

-fechaConexao();

-pegaConexao();

}

Quando vc for utilizar um comando SELECT por exemplo em outra classe vc chama o metodo necessario no seu pool de conexao.

Daí vc fala de quando eu for fazer o select, eu chamo tipo: pegaConexao() e realizo o select??? assim por exemplo se meu select estiver dentro de outra classe ele irá aceitar? As váriaveis irão funcionar??

Valeu! 8)

fbanin

Foi isso que tentei dizer…

Vai funcionar…

Vc vai ter que fazer assim

MeuPoolConex c = new MeuPoolConex();
Statement st = c.conexao.createStatement();
ResultSet rsTabela = st.executeQuery("SELECT * FROM SYSOBJECTS");

Eu estou fazendo dessa maneira…

paulinhohd

fbanin:
Foi isso que tentei dizer…

Vai funcionar…

Vc vai ter que fazer assim

MeuPoolConex c = new MeuPoolConex();
Statement st = c.conexao.createStatement();
ResultSet rsTabela = st.executeQuery("SELECT * FROM SYSOBJECTS");

Eu estou fazendo dessa maneira…

E como ficou seu Pool de Conexão? (MeuPoolConex), quais funções vc colocou nele?Vc fez uma classe a parte então pelo que percebi…e depois dentro de outras classes vc está conseguindo fazer os Selects utilizando o código acima isso?

Valeu! 8)

fbanin

Isso ai, dentro dessa classe eu criei 3 métodos… um para abrir a conexão, outro para fechar e o construtor padrão que cria a conexão mesmo…

import java.sql.*;

public class Conexao{

	static public Connection conexao = null;

	public Conexao(){

		if( conexao == null )
			abreConexao();

	}

	public void abreConexao(){

		try{

			Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
			conexao = DriverManager.getConnection("jdbc:odbc:BDTesteJava", "", "");

		}
		catch(ClassNotFoundException e){

			System.out.println("Não achei a classe: " + e.getMessage());

		}
		catch(Exception e){

			System.err.println("Erro no acesso ao banco de dados !");

		}

	}

	public void fechaConexao(){

		try{

			conexao.close();

		}
		catch(SQLException e){

			System.err.println("Erro no fechamento da conexão...");

		}

	}

}

Esse ai foi um dos primeiros teste que eu fiz…

T+

paulinhohd

Valeu Fabiano, vou tentar aqui e qualquer coisa posto novamente…

Valeu! 8)

jmedeiros

o que fbanin disse esta correto e a classe dele também(pool)!

Se tiver dúvidas na implementação é só avisar!

paulinhohd

Ae pessoal, já to com dúvidas rs…

Adaptei o código do Fabiano ao meu para fazer uns testes.

Detalhe: Eu já tenho a minha class Principal, que é onde tenho todo meu applet, meu programa inteiro.

Para eu criar esta outra class, a PoolConexao, como faço para criá-la no memso arquivo?

Pois tentei colocá-la fora da Principal.class, porém quando quero fazer um select dentro da Principal ela não encontra as váriáveis, e se eu colocar dentro ai que zica de vez…o que estou fazendo de errado?

Se puderem me ajudar?

Valeu mesmo assim pela compreensão! :lol:

fbanin

Ai que esta, dentro da sua principal vc quer utilizar qual variavel ?!

se for a variavel (atributo) conexao, não vai dar mesmo, o que vc tem que fazer na sua classe principal é instanciar a conexão:

Conexao c = new Conexao();

Se a conexão já tiver sido aberta uma vez, ele não irá abrir de novo, porém sua referência a conexão vai estar apta a fazer o que vc quiser, ai na sua classe principal, para utilizar o "createStatement()" vc utiliza assim:

...
// Aqui eu chamo o meu construtor para abrir/pegar uma conexão.
Conexao con = new Conexao();

// Crio o Statement para poder mandar INSERTs/UPDATEs/SELECTs/etc
Statement st = con.conexao.createStatement();

// Aqui eu monto o meu resultset com um comando em uma tabela de teste.
ResultSet rsPessoas = st.executeQuery("SELECT * FROM PESSOAS");

// Vou para o próximo para ver se funcionou...
rsPessoas.next();
...

Depois de abrir a conexão vc não vai utilizar a variável que esta na classe Conexao, mas sim instanciar sempre uma referência para a conexão já existente (no caso de já ter sido aberta, caso contrário a abertura será feita de maneira automática) ai sim vc terá acesso a variavel de dentro da classe... (coisa que pretendo dar uma melhorada)...

Certo ?!

A

Me entrometendo na duvida do colega, tenho as minhas aqui !
Certo, criei uma classe de conexao, tenho meus tres metodos, conectar, abrir e fechar a conecao. Minha duvida pode ter sido respondido acima, mas … deixa eu explicar: Tenho uma classe de conexao e tres outras classes, Principal (modulo login) - Vendas (faco insert e delete) e Agendamento (faco selects). Tenho que instanciar minha classe de conecao nas tres? No caso de ser um sistema que mais de um usuario, como eu faco para manter pelo menos duas conecoes abertas ou nao preciso fecha-las ?? somente quando eu fechar de vez o aplicativo ?

Espero ter sido claro, mas isso vai clarear e muito para mim !

valew
[]s

fbanin

marsola2k:

Tenho uma classe de conexao e tres outras classes, Principal (modulo login) - Vendas (faco insert e delete) e Agendamento (faco selects). Tenho que instanciar minha classe de conecao nas tres?

Sim, teria que instanciar para as três, porém, na primeira vez que vc instanciar ele irá abrir a conexão… nas outras vezes ele já vai existir… o que pode ser feito, no login vc abre a conexão e pronto, deixa ela aberta, nos outros vc só instancia, ele não vai abrir novamente a conexão pois já foi aberta no login, ai vc usa conforme o caso que vc quer… como eu coloquei na resposta acima… qdo sair realmente do aplicativo vc instancia a classe de conexão novamente e da um close nela…

Com mais de um usuário sem problemas, pois ele irá abrir uma conexão para cada usuário… ou seja, se vc usar dois prompts do DOS e chamar duas vezes sua aplicação, vc terá uma conexão para cada instância de sua aplicação no Windows…

Alguém me corrija se estiver falando alguma baboseira…

paulinhohd

marsola2k:
Certo, criei uma classe de conexao, tenho meus tres metodos, conectar, abrir e fechar a conecao. Minha duvida pode ter sido respondido acima, mas … deixa eu explicar: Tenho uma classe de conexao e tres outras classes, Principal (modulo login) - Vendas (faco insert e delete) e Agendamento (faco selects). Tenho que instanciar minha classe de conecao nas tres? No caso de ser um sistema que mais de um usuario, como eu faco para manter pelo menos duas conecoes abertas ou nao preciso fecha-las ?? somente quando eu fechar de vez o aplicativo ?
[]s

Marsola, pelo pouco que sei o esquema é vc fechar a conexão ao encerrar o aplicativo.

Fabiano, me ou vc mesmo Marsola, como coloco várias classes : Conexao.class, Principal.class em um só arquivo, estou utilizando o Eclipse mas parece que ele não aceita muito isso, ou sou eu mesmo que to fazendo coisa errada rs…

Preciso criar a parte de conexão, e depois dentro de outra classe, realizar os Selects, só que o menino não aceita de jeito nenhum, já fiz com váriavel atributo, global, local e nada…

Por favor, Me ajudemmmm!!!

valeu galera!! 8)

fbanin
paulinhohd:
Fabiano, me ou vc mesmo Marsola, como coloco várias classes : Conexao.class, Principal.class em um só arquivo, estou utilizando o Eclipse mas parece que ele não aceita muito isso, ou sou eu mesmo que to fazendo coisa errada rs.......

Não vejo necessidade disso, mas seria assim:

public class Classe1{

   // métodos e atributos e bla bla bla

  public class Classe2{

     // métodos e atributos dessa classe...

   }

}

Não sei se no eclipse deixa, ainda não estou utilizando ele... mas já vi isso em um exemplo que baixei de layouts customizaveis para o Swing....

A

Nao chegei a testar no eclipse tb ! estou terminando um projeto no netBeans que ja comecei e quando fechar, começarei a migrar ! Mas que eu saiba, no netBEans 3.6 nao deixa criar mais de uma classe !! O que eu acho que vc pode tentar fazer é instanciar essa outra classe ! Eu fiz assim e deu certo

Minha aplicacao

ModuloPrincipal
subModulo1
subModulo2
subModulo3
subModulo4

Instancio os subModulo e funciona !

Nao sei se esclareceu a duvida

paulinhohd

Ok galera, vou pelejar mais um pouco qualquer coisa eu posto novamente,

Valeu pela colaboração de todos!

Abraços! 8)

A

uma outra duvida minha

sempre declaro o ResultSet, Stament e Connection como static final no construtor ou nao preciso disso !!?

valew

fbanin

somente como final…

No meu caso eu criei só para o Connection, já que o resultset não fica no pool de conexão… fica na minha outra classe onde eu manipulo as tabelas… não é interessante colocar os statments e resultsets no meu pool…

Pelo menos é o que eu acho…

paulinhohd
public class Conexao{
		Connection conexao = null;
		 
		 	public Conexao(){
		 
		 		if( conexao == null )
		 			abreConexao();
		 
		 	}
		 
		 	public void abreConexao(){
		 
		 		try{
		 
		 			Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
		 			conexao = DriverManager.getConnection("jdbc:odbc:Driver=" + 
		 				      "{Microsoft Access Driver (*.mdb)};" + 
		 				      "DBQ=C:\\Projeto\\Representantes\\Representantes 1.0\\bin\\Historico.mdb","","");
		 					 
		 		}
		 		catch(ClassNotFoundException e){
		 
		 			System.out.println("Não achei a classe: " + e.getMessage());
		 
		 		}
		 		catch(Exception e){
		 
		 			System.err.println("Erro no acesso ao banco de dados !");
		 
		 		}
		 
		 	}
		 
		 	public void fechaConexao(){
		 
		 		try{
		 
		 			conexao.close();
		 
		 		}
		 		catch(SQLException e){
		 
		 			System.err.println("Erro no fechamento da conexão...");
		 
		 		}
		 
		 	}
	}

Este é o meu Pool De Conexao!

Conexao con = new Conexao();
				Statement FluxoSQL = con.conexao.createStatement();
				ResultSet Resultados = FluxoSQL.executeQuery("SELECT Cliente FROM Tab_Cliente");
			 	Resultados.next();
			 	Cliente = Resultados.getString(1).trim();
			 	System.out.println("Cliente = " + Cliente);

Aqui é onde eu chamo a conexao, dentro de uma ação de um botão, e é aí onde ele não aceita as variáveis, o que devo fazer??

Lembrando, o meu pool de conexão é uma classe a parte e onde estou fazendo o select está dentro de outra classe....

Espero ter sido claro, fabiano, acho que agora consegui explicar meu problema para vc, se puder me informar sobre isso?

Valeu! 8)

fbanin

No seu pool a sua variavel Conexao não esta declarada como STATIC logo ela será sempre refeita… vc vai abrir a conexão uma porrada de vezes…

Note tb que na que eu mandei eu declarei como:

static public Connection conexao = null;

Vc declarou diferente:

Connection conexao = null;

Do jeito que vc fez ele só vai deixar usar as classes de herdar o objeto. Declara ela do jeito que coloquei que dá certo…

Ah, no botão vc esta usando tb o try{ … } catch{ … } certo ?! Senão dá erro tb

djorodrigo
faz esse pool de conexão de outra forma... sempre abre a conexão e deixa ela disponível para qualquer requisição de conexão a base...assim: O exemplo que implementei serve só para MS Access.. Olha o pool que implementei criando outra classe:
public class DAOFactory implements Serializable{
    private static DAOFactory instance;
    private Connection conexao = null;

    public static DAOFactory getInstance(){
        synchronized(DAOFactory.class){
           if(instance == null){
             instance = new DAOFactory();
           }
        }
        return instance;
    }

    private DAOFactory(){
        loadClass();
    }

    private void loadClass(){
         try{
 	Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
 	conexao = DriverManager.getConnection("jdbc:odbcriver=" + 
 	               "{Microsoft Access Driver (*.mdb)};" + 
                                "DBQ=C:\\Projeto\\Representantes\\Representantes 1.0\\bin\\Historico.mdb","","");
         }
         catch(ClassNotFoundException e){
 	System.out.println("Não achei a classe: " + e.getMessage());
         }
         catch(Exception e){
 	System.err.println("Erro no acesso ao banco de dados !");
         }
    }

    public Connection getConnection(){
       return conexao;
    }
}

para pegar a conexao faça assim:

Conexao con = DAOFactory.getInstance().getConnection();
Statement FluxoSQL = con.createStatement();
ResultSet Resultados = FluxoSQL.executeQuery("SELECT Cliente FROM Tab_Cliente");
Resultados.next();
Cliente = Resultados.getString(1).trim();
System.out.println("Cliente = " + Cliente);

Conseguiu entender??
Essa classe de factory de conexoes pode ser mto melhorada, mas
coloquei dessa forma só pra vc entender, inclusive utilizando pattern
Singleton.

A

Como seria a String para uma conexao Sql Server ?

a sua ficou assim:

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
  	conexao = DriverManager.getConnection("jdbc:odbcriver=" + 
  	               "{Microsoft Access Driver (*.mdb)};" + 
                                 "DBQ=C:\\Projeto\\Representantes\\Representantes 1.0\\bin\\Historico.mdb","","");

A minha esta assim:

private java.sql.Connection conectarBanco(String ip, String porta, String user, String pass) {
        try {
            String driver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
            String cnnString = "jdbc:microsoft:sqlserver://" + ip + ":" + porta + ":" + user + ":" + pass;
            Class.forName(driver);
            return java.sql.DriverManager.getConnection(cnnString);
        } catch(java.sql.SQLException erro) {
            erro.printStackTrace();
        } catch(Exception erro) {
            erro.printStackTrace();
        }
        return null;
    }

Se nao entenderem eu posto todo o codigo

Esse pool de conexao vc fez em outra classe ou manteve a mesma??

djorodrigo

criei uma outra classe para o pool de conexão…
se quiser pode criar uma classe interna, mas aí se outras classe precisarem utilizar o pool não irão conseguir, a não ser q vc criei um método de acesso para sua inner class de pool de conexões…

entendeu??

paulinhohd

fbanin:
static public Connection conexao = null;

Vc declarou diferente:

Connection conexao = null;

Do jeito que vc fez ele só vai deixar usar as classes de herdar o objeto. Declara ela do jeito que coloquei que dá certo…

Ah, no botão vc esta usando tb o try{ … } catch{ … } certo ?! Senão dá erro tb

Ae Fabiano, valeu, mas eu já havia tentado declarar identico a vc, porém não deu certo, mas acho que era porque não coloquei o try, cacth etc… vou fazer mais uns testes e qualquer coisa posto novamente…
Mesmo assim valeu!!! 8)

paulinhohd
djorodrigo:
faz esse pool de conexão de outra forma... sempre abre a conexão e deixa ela disponível para qualquer requisição de conexão a base...assim: O exemplo que implementei serve só para MS Access.. Olha o pool que implementei criando outra classe:
public class DAOFactory implements Serializable{
    private static DAOFactory instance;
    private Connection conexao = null;

    public static DAOFactory getInstance(){
        synchronized(DAOFactory.class){
           if(instance == null){
             instance = new DAOFactory();
           }
        }
        return instance;
    }

    private DAOFactory(){
        loadClass();
    }

    private void loadClass(){
         try{
 	Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
 	conexao = DriverManager.getConnection("jdbc:odbcriver=" + 
 	               "{Microsoft Access Driver (*.mdb)};" + 
                                "DBQ=C:\\Projeto\\Representantes\\Representantes 1.0\\bin\\Historico.mdb","","");
         }
         catch(ClassNotFoundException e){
 	System.out.println("Não achei a classe: " + e.getMessage());
         }
         catch(Exception e){
 	System.err.println("Erro no acesso ao banco de dados !");
         }
    }

    public Connection getConnection(){
       return conexao;
    }
}

para pegar a conexao faça assim:

Conexao con = DAOFactory.getInstance().getConnection();
Statement FluxoSQL = con.createStatement();
ResultSet Resultados = FluxoSQL.executeQuery("SELECT Cliente FROM Tab_Cliente");
Resultados.next();
Cliente = Resultados.getString(1).trim();
System.out.println("Cliente = " + Cliente);

Conseguiu entender??
Essa classe de factory de conexoes pode ser mto melhorada, mas
coloquei dessa forma só pra vc entender, inclusive utilizando pattern
Singleton.

Rodrigo, utilizarei seu exemplo, farei uns teste aqui, pois meu bd tb é no acess.......qualquer dúvida posto novamente........

Valeu!!!! 8)

Marsola, para SQL eu nunca pesquisei como se pega o driver, pois não sei se vc viu, mas eu usso colocando o caminho do BD para o usuário não precisar conectar, cnfigurar no ODBC, assim facilita as coisas para minha aplicação....
Desculpe, mas não sei como fica em SQL, o meu é para o Acess, mas não deve mudar muita coisa não, de uma olhada no portal dos Imasters, lá eles falam bem coisas de SQL.

Valeu! 8)

paulinhohd

djorodrigo:

Conseguiu entender??
Essa classe de factory de conexoes pode ser mto melhorada, mas
coloquei dessa forma só pra vc entender, inclusive utilizando pattern
Singleton.

Rodrigo, eu não entendi muito bem o que essa classe factory faz, e coloquei a biblioteca java.io para ele aceitar o implements Serializable, porém ele não está aceitando declarar a váriável instanceo Eclipse não está aceitando, o que fazer?

Valeu! 8)

A

Serializable o que isso faz ??

Existe alguma outra maneira de fazer o banco de dados receber os valores adicionados em uma classe? Assim, eu sempre crio uma classe para receber, no caso que retorne o valor recebido ??? dentro do ResultSet ??

valew

paulinhohd

marsola2k:
Existe alguma outra maneira de fazer o banco de dados receber os valores adicionados em uma classe? Assim, eu sempre crio uma classe para receber, no caso que retorne o valor recebido ??? dentro do ResultSet ??

valew

Como vc está inserindo os dados?
Vc quer dizer de buscar os dados no banco e exibí-los em um TextField por exemplo, ou ao contrário, O usuário digita os dados e envia para o banco?

Valeu! 8)

A

quando o usuario inserie o dado eu pego o que ele escreve no textField e boa,

txt_user.getText();

Mas no ResultSet eu declaro as variaveis e peco para retornar em uma classe que eu criei onde estao todos as variaveis, mas sera que eu poderia fazer diferente?

paulinhohd

Creio que tem como sim, mas como está seu ResultSet?

A

recebendo os valores que eu insiro no banco !!

paulinhohd

Se vc fizer o a classe com o Pool de Conexao corretamente, vc podera utilizar o resulset, utilizar qualquer select em qualquer classe, qualquer parte de seu programa, utilizando apenas o try e o catch.

Valeu! 8)

A

bem vou fazer alguns testes com isso e depois falo o que rolou !

valew

vc tem duas classes de conecao, correto?
uma para abrir e fechar a conection e outra para fazer o pool, neh

paulinhohd

marsola2k:
vc tem duas classes de conecao, correto?
uma para abrir e fechar a conection e outra para fazer o pool, neh

Meu Pool é uma classe na qual contem todas as funções que utilizo no banco e que meu pool está dentro de outra classe na qual é aprincipal de meu programa.

Qualquer dúvida posta ae!

Valeu! 8)

Criado 11 de abril de 2005
Ultima resposta 15 de abr. de 2005
Respostas 35
Participantes 5