W3docs

Introdução ao Java JDBC

O que é JDBC, como ele abstrai o acesso a bancos de dados em Java e a arquitetura da API JDBC.

JDBC (Java Database Connectivity) é a API padrão para comunicação com um banco de dados relacional a partir do Java. Ela reside nos pacotes java.sql e javax.sql e oferece uma forma neutra em relação ao fornecedor para abrir uma conexão, enviar SQL e ler resultados — seja o banco de dados PostgreSQL, MySQL, Oracle, SQL Server ou um mecanismo embutido como H2. Aprenda a API uma vez e apenas a URL de conexão muda quando você troca de banco de dados.

A grande ideia: uma camada fina e uniforme sobre muitos bancos de dados

Seu código é escrito contra interfacesConnection, Statement, ResultSet. As classes concretas que as implementam são distribuídas em um JAR de driver do fornecedor. O papel do JDBC é manter seu código no lado da interface dessa linha, de modo que a troca de banco de dados seja uma mudança de configuração, não uma reescrita.

Os tipos principais

Algumas interfaces aparecem em quase todos os programas JDBC:

InterfaceFunção
DriverManagerLocaliza um driver para sua URL e retorna uma Connection
ConnectionUma sessão ativa com o banco de dados; a fábrica de statements
StatementEnvia uma string SQL fixa
PreparedStatementEnvia um template SQL parametrizado (o padrão seguro)
CallableStatementInvoca uma stored procedure
ResultSetUm cursor sobre as linhas retornadas por uma consulta
SQLExceptionA exceção verificada que toda chamada JDBC pode lançar

A estrutura de todo programa JDBC

Quase todo acesso a dados segue os mesmos cinco passos. Veja como fica com um banco de dados real, usando try-with-resources para que cada recurso se feche automaticamente:

String url = "jdbc:postgresql://localhost:5432/shop";
String sql = "SELECT id, name FROM product WHERE price < ?";

try (Connection conn = DriverManager.getConnection(url, "app", "secret");
     PreparedStatement ps = conn.prepareStatement(sql)) {
  ps.setBigDecimal(1, new BigDecimal("9.99"));
  try (ResultSet rs = ps.executeQuery()) {
    while (rs.next()) {
      System.out.println(rs.getInt("id") + " " + rs.getString("name"));
    }
  }
}

Ou seja: (1) nomeie um banco de dados com uma URL, (2) abra uma Connection, (3) crie um statement, (4) execute-o, (5) leia o ResultSet — depois feche tudo na ordem inversa. O restante desta parte detalha cada passo.

Um sistema de tipos neutro em relação ao fornecedor

Colunas SQL não são tipos Java. O JDBC faz a ponte entre os dois com as constantes java.sql.TypesVARCHAR, INTEGER, TIMESTAMP e assim por diante — e um conjunto paralelo de métodos getXxx/setXxx. Raramente você enfrenta problemas com esse mapeamento, mas é por isso que uma coluna DATE vai e volta como java.sql.Date e um NUMERIC como BigDecimal.

Um exemplo prático: a porta de entrada, sem driver instalado

Este programa não se conecta a nada — ele inspeciona a própria maquinaria do JDBC. Ele pergunta ao DriverManager quais drivers estão registrados, mostra o contrato exato que você obtém quando nenhum corresponde a uma URL, e imprime algumas das constantes de tipo sobre as quais a API é construída.

java— editable, runs on the server

O que tirar da execução:

  • getConnection é o único ponto de entrada e é mediado pelo DriverManager. Você nunca cria uma conexão com new — você nomeia um banco de dados com uma URL e o JDBC roteia a requisição. O runtime aqui não tem nenhum driver registrado, então a contagem é 0.
  • Quando nenhum driver reivindica a URL, o JDBC não retorna null nem trava — ele lança SQLException com a mensagem 'No suitable driver found'. Todo método JDBC sinaliza falhas dessa forma, e é por isso que SQLException é verificada e você a trata em todo lugar.
  • A exceção carregou um SQLState (08001, a classe padrão 'client unable to establish connection'). Os códigos SQLState são portáveis entre fornecedores, ao contrário dos códigos de erro inteiros, que são específicos de cada fornecedor.
  • As constantes java.sql.Types são ints simples (VARCHAR é 12, INTEGER é 4). São a forma como a API nomeia tipos SQL independentemente de qualquer banco de dados, e você as passará para setNull e registerOutParameter em capítulos posteriores.
  • Nada aqui precisou de um banco de dados. A API JDBC faz parte do JDK; apenas o driver é externo. Essa separação é todo o design — seu código compila e raciocina sobre tipos java.sql sem nenhum banco de dados à vista.

Quando usar o JDBC

O JDBC é a fundação sobre a qual toda ferramenta Java de acesso a dados de nível superior é construída. Mapeadores objeto-relacional como Hibernate ou JPA, construtores de consulta como jOOQ, e auxiliares mais leves como o JdbcTemplate do Spring — todos chamam o JDBC por baixo dos panos. Use o JDBC diretamente quando quiser controle total sobre o SQL, um conjunto mínimo de dependências, ou quando estiver aprendendo como a camada realmente funciona. Use um ORM quando preferir mapear linhas para objetos e evitar o código repetitivo. De qualquer forma, os conceitos desta parte — conexões, statements, result sets e transações — são o que essas ferramentas gerenciam para você.

O que o restante desta parte aborda

Carregando e escolhendo drivers, abrindo e configurando uma Connection, os três tipos de statements (Statement, PreparedStatement e CallableStatement), e navegando por um ResultSet, além de transações, atualizações em lote e leitura de metadados do banco de dados. O próximo capítulo começa onde toda conexão tem início: o driver.

Prática

Prática
Em um programa JDBC típico, por que o código da aplicação é escrito contra interfaces como Connection e ResultSet em vez de classes concretas?
Em um programa JDBC típico, por que o código da aplicação é escrito contra interfaces como Connection e ResultSet em vez de classes concretas?
Was this page helpful?