Oiii gente, a minhas classes dao estão somente com statement e eu gostaria de passa para preparestatement, poderiam me ajudar queridos?
packagesql;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importjava.util.ArrayList;importjava.util.List;importmodel.Cliente;publicclassAcessoClienteDAOimplementsClienteDAO{publicvoidinserir(Clientec)throwsAcessoClienteException{Connectionconexao=null;Statementcomando=null;try{conexao=Conexao.getConexao();comando=conexao.createStatement();Stringsql="INSERT INTO cliente VALUES ("+c.getCodc()+",'"+c.getNomec()+"','"+c.getFonec()+"')";comando.executeUpdate(sql);System.out.println(sql);comando.close();}catch(SQLExceptione){thrownewAcessoClienteException("erro de inserção de cliente",e);}finally{if(conexao!=null){try{conexao.close();}catch(SQLExceptione2){}}}}publicCliente[]buscarTodos()throwsAcessoClienteException{Connectionconexao=null;Statementcomando=null;try{conexao=Conexao.getConexao();comando=conexao.createStatement();Stringsql="SELECT * FROM cliente";ResultSetresultado=comando.executeQuery(sql);List<Cliente>lista=newArrayList<Cliente>();while(resultado.next()){intcodc=resultado.getInt("codc");Stringnomec=resultado.getString("nomec");Stringfonec=resultado.getString("fonec");lista.add(newCliente(codc,nomec,fonec));}resultado.close();comando.close();return(Cliente[])lista.toArray(newCliente[0]);}catch(SQLExceptione){e.printStackTrace();thrownewAcessoClienteException("erro de busca de cliente",e);}finally{if(conexao!=null){try{conexao.close();}catch(SQLExceptione2){}}}}}
Connection conexao = null;
PreparedStatement comando = null;
try
{
comando = conexao.prepareStatement("INSERT INTO cliente VALUES (?,?,?)");
comando.setInt(1, c.getCodc());
comando.setString(2, c.getNomec());
comando.setString(3, c.getFonec());
comando.execute();
comando.close();
}
catch(SQLException e)
{
throw new AcessoClienteException("erro de inserção de cliente", e);
}
Note que você deve especificar o indice do atributo a ser setado e pelo tipo!
Faça testes até que tenha o comportamente esperado.
Dê sempre preferência a usar PreparedStatement e nunca concatene os valores na sua query SQL, use sempre a interrogaçãozinha.
Depois pesquise sobre execução em lote com PreparedStatement, o que pode lhe dar um bom ganho de desempenho quando for fazer inserção ou update em lote (com uma massa de dados considerável).
Bah, eu não recomendaria fazer desse modo não.
Continua concatenando os valores com a query SQL, então que diferença faz usar PS (PreparedStatement)?
O legal é usar PS pra se reaproveitar a declaração, o banco já fica “experto” com isso e recebe só a diferença da bagaça, sem ter que reinterpretar toda a query novamente.
Por conta disso recomendamos veementemente que se use PS da maneira como o Vini e eu demonstramos acima.
Abraços!
V
ViniGodoy
Tchello:
Fui 18 segundos mais rápido Vini 8)
hahahaha
O teclado mais rápido do oeste.
T
Tchello
ViniGodoy:
Tchello:
Fui 18 segundos mais rápido Vini 8)
hahahaha
O teclado mais rápido do oeste.
Tananaaaaaann pananaaaam… (músiquinha do Enio Moricone, num filme do Clint Eastwood ).
Espero que tenham senso de humor e aceitem a brincadeira hehehehe
M
Mariana.Vecci
Gente muito obrigada!!
vou tentar aqui e ja falo se deu certinho!
beijokas
V
ViniGodoy
Ajustei o código ali em cima. Faltou passar o SQL dentro do código do preparedStatement.
M
Mariana.Vecci
Obrigada, o inserir então deu certo!
agora fiz o select de acordo com o exemplo acima:
publicCliente[]buscarTodos()throwsAcessoClienteException{Connectionconexao=null;PreparedStatementcomando=null;try{conexao=Conexao.getConexao();Stringsql="SELECT * FROM cliente";comando=conexao.prepareStatement(sql);ResultSetresultado=comando.executeQuery();List<Cliente>lista=newArrayList<Cliente>();while(resultado.next()){intcodc=resultado.getInt("codc");Stringnomec=resultado.getString("nomec");Stringfonec=resultado.getString("fonec");lista.add(newCliente(codc,nomec,fonec));}resultado.close();comando.close();return(Cliente[])lista.toArray(newCliente[0]);}catch(SQLExceptione){e.printStackTrace();thrownewAcessoClienteException("erro de busca de cliente",e);}finally{if(conexao!=null){try{conexao.close();}catch(SQLExceptione2){}}}}
e funcionou, mas mesmo tendo funcionado, ta correto?
Obrigada!
V
ViniGodoy
Está sim, mas o correto é fechar o statement no finally, assim como você fez com a conexão.
Agora, não era melhor retornar uma List ao invés de retornar um array?
M
Mariana.Vecci
certo, então retirei o comando.close() da parte de cima dos dois voids e os coloquei como você falou:
try
{
conexao.close();
comando.close();
}
Qual seria então a diferença retornando List ?
V
ViniGodoy
Eu prefiro retornar listas pois são mais fáceis de manipular. É fácil copiar uma lista para um set, ou colocada no interior de um tablemodel.
Seu método nem mudaria muito:
publicList<Cliente>buscarTodos(){Connectionconexao=null;PreparedStatementcomando=null;ResultSetresultado=null;try{try{conexao=Conexao.getConexao();Stringsql="SELECT * FROM cliente";comando=conexao.prepareStatement(sql);resultado=comando.executeQuery();List<Cliente>lista=newArrayList<Cliente>();while(resultado.next()){intcodc=resultado.getInt("codc");Stringnomec=resultado.getString("nomec");Stringfonec=resultado.getString("fonec");lista.add(newCliente(codc,nomec,fonec));}}finally{if(resultado!=null)resultado.close();if(comando!=null)comando.close();if(conexao!=null)conexao.close();}}catch(SQLExceptione){e.printStackTrace();thrownewAcessoClienteException("erro de busca de cliente",e);}}
É uma boa transformar a AcessoClienteException numa RuntimeException. Afinal, há muito poucas chances dela ocorrer, e você já tratou corretamente o fechamento da Conexão, Statement e do ResultSet. Assim o java não exige try…catch na hora de usar o método buscaCliente().
M
Mariana.Vecci
Não estou conseguindo acertar as "{}" sempre dá q falta ou tem a mais:
packagesql;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.util.ArrayList;importjava.util.List;importmodel.Cliente;publicclassAcessoClienteDAOimplementsClienteDAO{publicvoidinserir(Clientec)throwsAcessoClienteException{Connectionconexao=null;PreparedStatementcomando=null;try{conexao=Conexao.getConexao();Stringsql="INSERT INTO cliente VALUES (?, ?, ?)";comando=conexao.prepareStatement(sql);comando.setInt(1,c.getCodc());comando.setString(2,c.getNomec());comando.setString(3,c.getFonec());comando.executeUpdate();System.out.println(sql);}catch(SQLExceptione){thrownewAcessoClienteException("erro de inserção de cliente",e);}finally{if(conexao!=null){try{conexao.close();comando.close();}catch(SQLExceptione2){}}}}publicList<Cliente>buscarTodos(){Connectionconexao=null;PreparedStatementcomando=null;ResultSetresultado=null;try{try{conexao=Conexao.getConexao();Stringsql="SELECT * FROM cliente";comando=conexao.prepareStatement(sql);resultado=comando.executeQuery();List<Cliente>lista=newArrayList<Cliente>();while(resultado.next()){intcodc=resultado.getInt("codc");Stringnomec=resultado.getString("nomec");Stringfonec=resultado.getString("fonec");lista.add(newCliente(codc,nomec,fonec));}}finally{if(resultado!=null)resultado.close();if(comando!=null)comando.close();if(conexao!=null)conexao.close();}catch(SQLExceptione){e.printStackTrace();thrownewAcessoClienteException("erro de busca de cliente",e);}}}}
eu tenho mais duas classes: produto e pedido, e ambas tem esta classe de exception, se eu mudar para runtime ai seria uma classe então para todas?
Obrigada!
V
ViniGodoy
Alterei ali as chaves. Tinha mesmo um erro.
A única diferença do RuntimeException é que não necessariamente elas precisam ser capturadas com try...catch. É ideal pra essas exceções que não tem muito tratamento, como a falha do banco de dados.
E aí não precisa mais colocar nada no "throws" dos seus métodos.
M
Mariana.Vecci
Arrumei ja os exceptions e ja ajeitei o método que tava com o problema do {}
mas agora ele ta reclando para add um statement return ou mudar para void,
se eu arrumar pelo primeiro jeito ele add um "return null" la em baixo, não sei se é o correto, mas pelo menos ele não acusa mais nenhum erro.
}catch(SQLExceptione){
e.printStackTrace();thrownewAcessoClienteException("erro de busca de cliente",e); }
returnnull;}
Muito obrigada pela ajuda até agora, o código ja mudou bastante graças a vocês!
EDIT: da erro: [color=red]sql.AcessoClienteException: AcessoClienteException: erro de inserção de cliente[/color]
E qual é o stack trace do erro, que sai impresso no console?
M
Mariana.Vecci
oiii,ali em baixo na parte problems mostra:“This method must return a result of type List”
e ali no console mostra:"Exception in thread “main” java.lang.Error: Unresolved compilation problem:
This method must return a result of type List
at sql.AcessoClienteDAO.buscarTodos(AcessoClienteDAO.java:50)
at sql.TesteClienteDAO.main(TesteClienteDAO.java:18)"
Obrigada!
V
ViniGodoy
Pode postar a versão final do seu método novamente?
M
Mariana.Vecci
siiim:
packagesql;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.util.ArrayList;importjava.util.List;importmodel.Cliente;publicclassAcessoClienteDAOimplementsClienteDAO{publicvoidinserir(Clientec)throwsAcessoClienteException{Connectionconexao=null;PreparedStatementcomando=null;try{conexao=Conexao.getConexao();Stringsql="INSERT INTO cliente VALUES (?, ?, ?)";comando=conexao.prepareStatement(sql);comando.setInt(1,c.getCodc());comando.setString(2,c.getNomec());comando.setString(3,c.getFonec());comando.executeUpdate();System.out.println(sql);}catch(SQLExceptione){thrownewAcessoClienteException("erro de inserção de cliente",e);}finally{if(conexao!=null){try{conexao.close();comando.close();}catch(SQLExceptione2){}}}}publicList<Cliente>buscarTodos(){Connectionconexao=null;PreparedStatementcomando=null;ResultSetresultado=null;try{try{conexao=Conexao.getConexao();Stringsql="SELECT * FROM cliente";comando=conexao.prepareStatement(sql);resultado=comando.executeQuery();List<Cliente>lista=newArrayList<Cliente>();while(resultado.next()){intcodc=resultado.getInt("codc");Stringnomec=resultado.getString("nomec");Stringfonec=resultado.getString("fonec");lista.add(newCliente(codc,nomec,fonec));}}finally{if(resultado!=null)resultado.close();if(comando!=null)comando.close();if(conexao!=null)conexao.close();}}catch(SQLExceptione){e.printStackTrace();thrownewAcessoClienteException("erro de busca de cliente",e);}}}
oii gente, não quis abrir outro tópico pq ta relacionado mesmo problema e tema, se eu errei, desculpa!
fui arrumar o preparedstatement do inserir pedido mas não deu certo, acho que é por causa das chavez estrangeiras de cliente e videogame
packagesql;importjava.sql.Connection;importjava.sql.SQLException;importjava.sql.Statement;importmodel.Pedido;importmodel.Cliente;importmodel.VideoGame;publicclassAcessoPedidoDAOimplementsPedidoDAO{publicvoidinserir(Pedidop)throwsAcessoPedidoException{Connectionconexao=null;Statementcomando=null;try{conexao=Conexao.getConexao();//String sql = "INSERT INTO pedido VALUES ("+p.getCodp()+",'"+p.getCliente().getCodc()+"','"+p.getVideogame().getCodvg()+")";Stringsql="INSERT INTO pedido VALUES (?, ?, ?)";comando=conexao.prepareStatement(sql);comando.setInt(1,p.getCodp());comando.setInt(2,p.getCliente().getCodc());comando.setInt(3,p.getVideogame().getCodvg());comando.executeUpdate();System.out.println(sql);}catch(SQLExceptione){thrownewAcessoPedidoException("erro de inserção de pedido",e);}finally{if(conexao!=null){try{conexao.close();}catch(SQLExceptione2){}}}}}
Obrigada!
T
tmagostinho
Também gostaria muito de usar preparestatement mas o problema é que faço query’s do género:
rs = query.select("SELECT * FROM car WHERE matricula like '"+matricula+"%'");
E assim dá um erro nos parâmetros do sql como se os parâmetros estivessem errados! :S
ps: não posso fazer o post do código do erro pois tinha que entregar o trabalho na faculdade e voltei ao statament