Classes

JDBC

Trabalhando com conexões SQL utilizando Java JDBC

O JDBC (Java Database Connectivity) é a API padrão do Java para comunicação com bancos de dados relacionais.
Com ele conseguimos:

  • abrir conexões com banco de dados
  • executar comandos SQL
  • consultar registros
  • atualizar dados
  • percorrer resultados retornados pelo banco

As principais interfaces utilizadas são:

Classe / InterfaceDescrição
java.sql.ConnectionRepresenta uma conexão ativa com o banco de dados
java.sql.PreparedStatementRepresenta uma instrução SQL parametrizada
java.sql.ResultSetRepresenta o resultado de uma consulta SQL
java.sql.DriverManagerResponsável por criar conexões JDBC

Java Doc

Dependência JDBC

Para conectar ao banco é necessário possuir o driver JDBC da tecnologia utilizada.

Exemplo com MySQL utilizando Maven:

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>9.0.0</version>
</dependency>

Abrindo conexão com banco de dados

import java.sql.Connection;
import java.sql.DriverManager;

public class ConexaoBanco {

    public static void main(String[] args) throws Exception {

        String url = "jdbc:mysql://localhost:3306/javadb";
        String usuario = "root";
        String senha = "123456";

        Connection connection =
                DriverManager.getConnection(url, usuario, senha);

        System.out.println("Conectado com sucesso!");

        connection.close();
    }
}
ParteDescrição
jdbc:mysqlTipo do banco
localhostEndereço do servidor
3306Porta do banco
javadbNome do banco

Sempre feche a conexão após o uso para evitar vazamento de recursos. ::

Connection

A interface Connection representa uma conexão ativa com o banco de dados.

Com ela podemos:

  • abrir transações
  • criar statements
  • executar commit e rollback
  • encerrar conexão

Exemplo utilizando try-with-resources

import java.sql.Connection;
import java.sql.DriverManager;

public class ExemploConnection {

    public static void main(String[] args) throws Exception {

        String url = "jdbc:mysql://localhost:3306/javadb";

        try (
            Connection connection =
                DriverManager.getConnection(url, "root", "123456")
        ) {

            System.out.println("Conexão aberta!");

        }
    }
}

O try-with-resources fecha automaticamente a conexão. ::

PreparedStatement

O PreparedStatement é utilizado para executar SQL parametrizado de forma segura.

Ele evita:

  • SQL Injection
  • concatenação manual de strings
  • erros de formatação

Inserindo dados

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class InserindoDados {

    public static void main(String[] args) throws Exception {

        String url = "jdbc:mysql://localhost:3306/javadb";

        String sql = """
            INSERT INTO usuarios(nome,email)
            VALUES (?, ?)
        """;

        try (
            Connection connection =
                DriverManager.getConnection(url, "root", "123456");

            PreparedStatement ps =
                connection.prepareStatement(sql)
        ) {

            ps.setString(1, "Gleyson");
            ps.setString(2, "gleyson@email.com");

            ps.executeUpdate();

            System.out.println("Usuário inserido!");
        }
    }
}

Atualizando registros

String sql = """
    UPDATE usuarios
       SET email = ?
     WHERE id = ?
""";

PreparedStatement ps =
        connection.prepareStatement(sql);

ps.setString(1, "novo@email.com");
ps.setLong(2, 1L);

ps.executeUpdate();

Removendo registros

String sql = "DELETE FROM usuarios WHERE id = ?";

PreparedStatement ps =
        connection.prepareStatement(sql);

ps.setLong(1, 1L);

ps.executeUpdate();

Executando consultas SQL

String sql = "SELECT * FROM usuarios WHERE nome = ?";

PreparedStatement ps =
        connection.prepareStatement(sql);

ps.setString(1, "Gleyson");

Os índices dos parâmetros começam em 1. ::

ResultSet

O ResultSet representa os dados retornados por uma consulta SQL.

Ele funciona como um cursor que percorre linha por linha.

Consultando dados

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

public class ConsultandoDados {

    public static void main(String[] args) throws Exception {

        String url = "jdbc:mysql://localhost:3306/javadb";

        String sql = """
            SELECT id,nome,email
              FROM usuarios
        """;

        try (
            Connection connection =
                DriverManager.getConnection(url, "root", "123456");

            PreparedStatement ps =
                connection.prepareStatement(sql);

            ResultSet rs = ps.executeQuery()
        ) {

            while (rs.next()) {

                Long id = rs.getLong("id");
                String nome = rs.getString("nome");
                String email = rs.getString("email");

                System.out.println(id);
                System.out.println(nome);
                System.out.println(email);
            }
        }
    }
}

Métodos comuns do ResultSet

MétodoDescrição
next()Move para próxima linha
getString()Obtém texto
getInt()Obtém inteiro
getLong()Obtém Long
getDouble()Obtém decimal
getDate()Obtém data

Executando transações

Transações garantem consistência dos dados.

Exemplo com commit e rollback

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class Transacao {

    public static void main(String[] args) throws Exception {

        String url = "jdbc:mysql://localhost:3306/javadb";

        Connection connection =
                DriverManager.getConnection(url, "root", "123456");

        try {

            connection.setAutoCommit(false);

            String sql = """
                INSERT INTO usuarios(nome)
                VALUES (?)
            """;

            PreparedStatement ps =
                    connection.prepareStatement(sql);

            ps.setString(1, "João");

            ps.executeUpdate();

            connection.commit();

        } catch (Exception ex) {

            connection.rollback();

        } finally {

            connection.close();
        }
    }
}

Diferença entre executeQuery e executeUpdate

MétodoUtilização
executeQuery()Consultas SELECT
executeUpdate()INSERT, UPDATE e DELETE
execute()SQL genérico

Boas práticas com JDBC

  • Utilize PreparedStatement em vez de Statement
  • Sempre feche Connection, PreparedStatement e ResultSet
  • Prefira try-with-resources
  • Nunca concatene parâmetros diretamente no SQL
  • Separe regras SQL da camada de negócio
  • Utilize pool de conexões em aplicações reais

Exemplo de SQL Injection

❌ Evite isso:

String sql =
    "SELECT * FROM usuarios WHERE nome = '" + nome + "'";

✅ Prefira:

String sql =
    "SELECT * FROM usuarios WHERE nome = ?";

PreparedStatement ps =
        connection.prepareStatement(sql);

ps.setString(1, nome);

Fluxo comum JDBC

1. Abrir conexão
2. Criar PreparedStatement
3. Definir parâmetros
4. Executar SQL
5. Ler ResultSet (quando SELECT)
6. Fechar recursos

Estrutura típica em camadas

controller
service
repository
database

O JDBC normalmente fica concentrado na camada Repository/DAO. ::

Próximos passos

Depois de aprender JDBC puro, os próximos níveis normalmente são:

  • Pool de conexões
  • DAO Pattern
  • JPA e Hibernate
  • Spring Data JPA
  • Mapeamento Objeto Relacional (ORM)
  • Paginação e performance SQL
  • Transações avançadas
  • Stored Procedures

Banco H2 para testes locais

O H2 é um banco em memória muito utilizado para estudos e testes.

Dependência Maven

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.3.232</version>
</dependency>

URL de conexão H2

String url = "jdbc:h2:mem:testdb";

Excelente opção para aprender JDBC sem instalar banco de dados.