Drivers de Banco de Dados
Definição de Driver de Banco
Um driver de banco de dados consiste em um arquivo JAR fornecido pelo fbaricante do banco para permitir a interação com o sistema de gerenciamento de banco de dados.
Visão Geral do JDBC
O que é JDBC
JDBC (Java Data base Connectivity) representa uma especificação da Sun Microsystems que estabelece interfaces padronizadas para acesso a bancos de dados relacionais. Como diferentes fornecedores implementam seus próprios drivers seguindo estas interfaces, os desenvolvedores precisam aprender apenas um conjunto único de APIs para trabalhar com diversos bancos de dados.
Pacotes JDBC
As funcionalidades principais do JDBC estão contidas nos pacotes java.sql e javax.sql, que fazem parte do Java SE. Para desenvolver aplicações com banco de dados, é necessário incluir também o driver específico do banco que será utilizado.
Fluxo Básico de Operações JDBC
O processo padrão para execução de operações com JDBC envolve seis etapas principais:
- Registro do driver do banco
- Estabelecimento da conexão
- Criação do objeto de statement
- Execução da consulta SQL
- Processamento dos resultados
- Liberação dos recursos
Connection conexao = null;
Statement declaracao = null;
ResultSet resultado = null;
try {
// Registrar driver
Class.forName("com.mysql.jdbc.Driver");
// Estabelecer conexão
conexao = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/empresa", "admin", "senha123");
// Criar statement
declaracao = conexao.createStatement();
// Executar consulta
resultado = declaracao.executeQuery("SELECT id, nome FROM funcionarios");
// Processar resultados
while(resultado.next()) {
int id = resultado.getInt("id");
String nome = resultado.getString("nome");
System.out.println("ID: " + id + ", Nome: " + nome);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
// Fechar recursos
try {
if(resultado != null) resultado.close();
if(declaracao != null) declaracao.close();
if(conexao != null) conexao.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Operações CRUD - Exemplo de Exclusão
Configuração via Arquivo de Propriedades
Crie um arquivo config.properties com:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/empresa
usuario=admin
senha=senha123
Classe Utilitária para Conexão
public class GerenciadorConexao {
private static Properties config = new Properties();
static {
try {
InputStream entrada = GerenciadorConexao.class
.getClassLoader().getResourceAsStream("config.properties");
config.load(entrada);
} catch (IOException e) {
throw new RuntimeException("Erro ao carregar configurações", e);
}
}
public static Connection obterConexao() throws SQLException {
String driver = config.getProperty("driver");
String url = config.getProperty("url");
String usuario = config.getProperty("usuario");
String senha = config.getProperty("senha");
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new SQLException("Driver não encontrado", e);
}
return DriverManager.getConnection(url, usuario, senha);
}
}
Implementação da Exclusão
Connection conexao = null;
Statement declaracao = null;
try {
conexao = GerenciadorConexao.obterConexao();
declaracao = conexao.createStatement();
int linhasAfetadas = declaracao.executeUpdate(
"DELETE FROM produtos WHERE categoria = 'obsoletos'");
System.out.println(linhasAfetadas + " registros removidos");
} catch (SQLException e) {
throw new RuntimeException("Erro na exclusão", e);
} finally {
// Fechar recursos
}
Proteção contra SQL Injection
O Problema
O ataque por injeção de SQL ocorre quando entradas do usuário contendo comandos SQL maliciosos são concatenadas diretamente nas consultas, alterando seu comportamento original.
Solução com PreparedStatement
O PreparedStatement utiliza compilação prévia, onde a estrutura da consulta é definida entecipadamente e os parâmetros são tratados como valores, não como parte do código SQL.
public void inserirCliente(Cliente cliente) {
Connection conexao = null;
PreparedStatement ps = null;
try {
conexao = GerenciadorConexao.obterConexao();
ps = conexao.prepareStatement(
"INSERT INTO clientes (nome, email, telefone) VALUES (?, ?, ?)");
ps.setString(1, cliente.getNome());
ps.setString(2, cliente.getEmail());
ps.setString(3, cliente.getTelefone());
ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Erro ao inserir cliente", e);
} finally {
// Liberar recursos
}
}
Processamento em Lote
Utilizando Statement
Connection conexao = GerenciadorConexao.obterConexao();
Statement stmt = conexao.createStatement();
stmt.addBatch("INSERT INTO logs (mensagem) VALUES ('Operação 1')");
stmt.addBatch("UPDATE contadores SET valor = valor + 1");
stmt.addBatch("DELETE FROM temporarios WHERE expirado = true");
int[] resultados = stmt.executeBatch();
Utilizando PreparedStatement
String sql = "INSERT INTO pedidos (cliente_id, valor) VALUES (?, ?)";
PreparedStatement ps = conexao.prepareStatement(sql);
for(int i = 0; i < 1000; i++) {
ps.setInt(1, i + 1000);
ps.setDouble(2, Math.random() * 1000);
ps.addBatch();
if(i % 100 == 0) {
ps.executeBatch();
ps.clearBatch();
}
}
ps.executeBatch();
Pool de Conexões
Configuração do C3P0
Arquivo c3p0-config.xml:
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost/empresa</property>
<property name="user">admin</property>
<property name="password">senha123</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
</c3p0-config>
Uso do Pool
ComboPooledDataSource pool = new ComboPooledDataSource();
Connection conexao = pool.getConnection();
// Utilizar conexão normalmente
// ...
conexao.close(); // Devolve a conexão ao pool
Controle de Transações
Gerenciamento Manual
Connection conexao = null;
try {
conexao = GerenciadorConexao.obterConexao();
conexao.setAutoCommit(false);
// Executar múltiplas operações
executarOperacao1(conexao);
executarOperacao2(conexao);
conexao.commit();
} catch (SQLException e) {
if(conexao != null) {
try {
conexao.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
throw new RuntimeException("Transação falhou", e);
} finally {
// Restaurar auto-commit e fechar conexão
}
Pontos de Salvamento (Savepoints)
conexao.setAutoCommit(false);
Savepoint ponto1 = conexao.setSavepoint("PONTO_1");
// Executar algumas operações
Savepoint ponto2 = conexao.setSavepoint("PONTO_2");
// Executar mais operações
// Reverter até ponto específico
conexao.rollback(ponto1);
conexao.commit();