Diferença entre Statement e PreparedStatement

5 respostas
J

Pessoal tudo bem.

Gostaria de saber qual é a diferença entre o Statement e o PreparedStatement?

Estou fazendo alguns testes com consultas em um DB e fiquei com essa dúvida, pelo que percebi essas duas classes são muito parecidas quando ao seu uso.

Desde já agradeço a atenção de todos.

5 Respostas

drsmachado

Parecidas? Tem certeza?
Veja e conclua…
Com Statement

String query = "SELECT col1, col2, col3 FROM tabela WHERE col4 = 'Teste'";
Statement stm = con.createStatement();
ResultSet rs = stm.executeQuery(query);

Notou a presença do parâmetro diretamente na query?
Outro exemplo

String query = "UPDATE table SET nome = 'Joana', sobrenome = 'D'arc' WHERE id = 10";
Statement stm = con.createStatement(query);
stm.execute();

Será que a query acima roda?
Já com PreparedStatement

String query = "SELECT col1, col2, col3 FROM tabela WHERE col4 = ?";
PreparedStatement pstm = con.prepareStatement(query);
pstm.setString(1, 'Teste');
pstm.execute();
ResultSet rs = pstm.getResultSet();

E quando vou fazer um update

String query = "UPDATE table SET nome = ?, sobrenome = ? WHERE id = ?";
PreparedStatement pstm = con.createStatement(query);
pstm.setString(1, "Joana");
pstm.setString(2, "D'arc");
pstm.setInt(3, 10);
pstm.execute();

Percebe?
O Statement trará, além de problemas com nomes que contém apóstrofos (como Joana D`Arc), a fragilidade à SQL Injection.
PreparedStatement não tem problemas com apóstrofos nem com SQL Injection (num nível óbvio, talvez um mais elaborado possa ocorrer, nada é 100%).

rmendes08

A diferença é que o PreparedStatement mantém uma versão compilada da consulta no BD. Ele é especialmente útil quando você precisa executar uma mesma consulta várias vezes mas com valores diferentes para os parâmetros. Na verdade, nem parâmetros você pode usar com o Statement …

Exemplo:

public List<Compra> findComprasByClienteId(List<Integer> ids) throws Exception{
  PreparedStatement st = ConnectionFactory.getConnection().prepareStatement("select * from Compras where idCliente = ?);
  
  List<Compras> result = new ArrayList<Compra>();

  for(Integer id : ids){
     st.setInt(1, id);

     ResultSet rset = st.executeQuery();
     
     while(rset.next){
            result.add(getCompraFromResultSet(rs));     
     }
     
     rset.close();
  }

  st.close();

  return result;
}

Com Statement você precisaria criar um objeto para cada id na lista. Até mesmo porque você precisaria criar uma nova consulta no banco para cada iteração.

Pode parecer um detalhe insignificante, mas a diferença no tempo de execução é absurda;

EduFrazao

Porém as diferenças vão além da “API de injeção de parâmetros”.

Statements preparados registram querys com parâmetros não literais diretamente no Banco de Dados. Dessa forma, o Query Planner pode reutilizar seus planos, caso você use a mesma query, apenas com valores de parâmetros diferentes, o que não ocorreria com valores literais.

ViniGodoy

Acho que a primeira resposta ressaltou as diferenças “quanto ao uso”, que foi o que o autor ressaltou na pergunta.

Quanto a execução, outra diferença que vale citar é que o PreparedStatement envia os dados de forma binária ao banco. Isso otimiza o uso da conexão, expecialmente no caso de bulk operations.

J

Ok, pessoal agradeço a todos pelas respostas.

Sanou a minha dúvida e ainda deu um “UP” no conhecimento.

Obrigado.

Falow…

Criado 22 de maio de 2013
Ultima resposta 22 de mai. de 2013
Respostas 5
Participantes 5