Prepared

Statement vs PreparedStatement: quais as diferenças?

A Joana colocou a seguinte pergunta sobre Statement vs PreparedStatement no artigo JDBC: Acessando Bancos de Dados em Java:

Olá professor,
Quais são as diferenças entre Statement e prepareStatement?

E, ao invés de responder diretamente no comentário, achei que a resposta valia um post! 🙂

Conceito

Bom, vamos direto ao ponto: a principal diferença entre o Statement e o PreparedStatement é que o PreparedStatement é “preparado” no banco de dados, tornando-o mais rápido. Ou seja, se você fizer diversas consultas parecidas, onde só mudam alguns valores, ele executa mais rapidamente do que se você fizer várias consultas usando o Statement.

Isso acontece porque quando uma consulta chega no banco de dados para ser executada, ela tem que passar por diversos passos de preparação até ser realmente processada. Ao usar o Statement, esses passos são feitos a cada consulta. Já no PreparedStatement, esses passos são feitos apenas uma vez.

Vamos ver um exemplo: imagine que você quer fazer as seguintes consultas:

[code lang=”sql”]
insert into usuarios (nome, idade) values (‘Amanda’, 35);
insert into usuarios (nome, idade) values (‘Bruno’, 22);
insert into usuarios (nome, idade) values (‘Carlos’, 29);
[/code]

Statement

Você pode criar um Statement e chamar o método executeUpdate para cada uma das consultas, assim:

[code lang=”java”]
Statement stmt = conn.createStatement();

stmt.executeUpdate("insert into usuarios (nome, idade) values (‘Amanda’, 35)");
stmt.executeUpdate("insert into usuarios (nome, idade) values (‘Bruno’, 22)");
stmt.executeUpdate("insert into usuarios (nome, idade) values (‘Carlos’, 29)");
[/code]

PreparedStatement

Ou, então, criar um PreparedStatement que será enviado para o banco de dados e que, por sua vez, irá fazer todos os passos de preparação antes da execução definitiva. Logo após, basta mudar os valores das variáveis (?) e enviá-las para execução no banco, assim:

[code lang=”java”]
PreparedStatement stmt = conn.prepareStatement("insert into usuarios (nome, idade) values (?, ?)");

stmt.setString(1, "Amanda");
stmt.setString(2, "35");
stmt.executeUpdate();

stmt.setString(1, "Bruno");
stmt.setString(2, "22");
stmt.executeUpdate();

stmt.setString(1, "Carlos");
stmt.setString(2, "29");
stmt.executeUpdate();
[/code]

Lógico que você não irá notar muita diferença de velocidade ao enviar apenas três consultas para o banco de dados, mas se você estiver fazendo isso muuuuuitas vezes, o PreparedStatement pode ajudar.

Fazendo um teste com a inserção de 1.000.000 usuários em uma tabela similar à do exemplo, obtive os seguintes resultados:

Tipo Tempo Total (ms) Tempo Total (min) Tempo por Consulta (ms)
Statement 714386 11,9 0,714
PreparedStatement 657988 10,9 0,658

Isso significa que, no meu teste, o PreparedStatement foi aproximadamente 7,9% mais rápido que o Statement!

SQL Injection

É interessante notar que, para que você possa mudar os valores, o PreparedStatement tem esse mecanismos de alteração dos valores por meio dos métodos setString, setInt, etc. Isso traz um efeito colateral benéfico que é prevenir ataques de SQL Injection, uma vez que esses métodos fazem o tratamento dos valores sendo enviados.

Conclusão

Se você for fazer muitas consultas onde apenas os valores mudam, use o PreparedStatement. Se não for o caso, use o PreparedStatement mesmo assim, para evitar ataques de SQL Injection. 🙂

Até a próxima!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *