Como usar PreparedStatement em vez de Statement?

O uso de PreparedStatement em vez de Statement em Java melhora a segurança contra SQL Injection e otimiza o desempenho das consultas SQL.

Como usar PreparedStatement em vez de Statement?

O PreparedStatement é uma alternativa mais segura e eficiente ao Statement no JDBC. Ele permite executar consultas SQL parametrizadas, prevenindo SQL Injection e melhorando a performance do banco de dados ao reutilizar instruções pré-compiladas.

1. Problemas do Uso de Statement

O Statement executa consultas diretamente no banco de dados, permitindo a concatenação de strings nas queries, o que pode abrir brechas para SQL Injection.

Statement stmt = conexao.createStatement();
String usuario = "admin' OR '1'='1"; // Entrada maliciosa
String sql = "SELECT * FROM usuarios WHERE nome = '" + usuario + "'";
ResultSet rs = stmt.executeQuery(sql);

Problema: Essa abordagem permite manipular a consulta e acessar todos os registros sem autenticação.

2. Como PreparedStatement Resolve o Problema?

O PreparedStatement utiliza parâmetros (?) para separar a lógica SQL dos valores de entrada, prevenindo ataques de injeção de código e melhorando a eficiência da execução de queries repetidas.

Exemplo de Uso do PreparedStatement

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ExemploPreparedStatement {
    public static void main(String[] args) {
        String sql = "SELECT * FROM usuarios WHERE nome = ?";

        try (Connection conexao = ConexaoJDBC.conectar();
             PreparedStatement stmt = conexao.prepareStatement(sql)) {

            stmt.setString(1, "João"); // Definindo parâmetro seguro
            ResultSet rs = stmt.executeQuery();

            while (rs.next()) {
                System.out.println("Nome: " + rs.getString("nome"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Explicação: O ? indica um espaço reservado, e setString(1, "João") substitui esse espaço pelo valor seguro.

3. Melhorando a Performance com PreparedStatement

O banco de dados pré-compila o SQL e o mantém em cache, otimizando consultas repetidas.

String sql = "INSERT INTO produtos (nome, preco) VALUES (?, ?)";
try (PreparedStatement stmt = conexao.prepareStatement(sql)) {
    stmt.setString(1, "Notebook");
    stmt.setDouble(2, 3500.00);
    stmt.executeUpdate();
}

Explicação: Em operações repetitivas, como múltiplos INSERT, o PreparedStatement reutiliza a estrutura SQL sem recompilar, acelerando a execução.

4. Comparação entre Statement e PreparedStatement

Característica Statement PreparedStatement
Segurança Baixa (suscetível a SQL Injection) Alta (evita SQL Injection)
Performance Menos eficiente em consultas repetitivas Melhor performance com reutilização
Parametrização Não suporta parâmetros Usa placeholders (?)
Código mais limpo Não Sim

5. Boas Práticas ao Usar PreparedStatement

  • Sempre feche PreparedStatement após o uso para evitar vazamento de memória.
  • Use setInt(), setDouble(), setDate(), etc., para definir os tipos corretamente.
  • Evite reusar um PreparedStatement com SQL dinâmico, pois ele perde a vantagem da pré-compilação.

Conclusão

Utilizar PreparedStatement no lugar de Statement é uma melhor prática essencial para qualquer aplicação Java que interaja com bancos de dados. Além de proteger contra SQL Injection, ele melhora a performance e facilita a manutenção do código.

A utilização de PreparedStatement é uma das formas mais eficazes de garantir segurança e desempenho em aplicações Java que interagem com bancos de dados. Grandes sistemas, como ERPs e CRMs, processam milhares de consultas diariamente, e otimizar essas operações reduz o consumo de recursos e melhora a experiência do usuário.

Algumas aplicações:

  • Prevenção contra ataques de SQL Injection
  • Melhoria no desempenho de consultas repetidas
  • Facilidade na manutenção do código SQL
  • Execução segura de operações com bancos de dados

Dicas para quem está começando

  • Use sempre PreparedStatement para consultas parametrizadas
  • Evite concatenar strings em consultas SQL
  • Defina os tipos corretos com setInt(), setDouble(), etc.
  • Feche a conexão e o statement após o uso
  • Utilize ORM como Hibernate para abstrair o acesso ao banco

Contribuições de Rodrigo Farias

Compartilhe este tutorial: Como usar PreparedStatement em vez de Statement

Compartilhe este tutorial

Continue aprendendo:

Como prevenir SQL Injection em Java

A prevenção contra SQL Injection em Java é essencial para garantir a segurança de aplicações que interagem com bancos de dados.

Tutorial anterior

Como recuperar dados de um banco de dados usando Java

Recuperar dados de um banco de dados em Java envolve o uso de JDBC para executar consultas SQL e processar os resultados com ResultSet.

Próximo tutorial