🚀 Capítulo 16: Padrão DAO (Data Access Object)

🎯 Objetivo da Aula

Ao final desta aula, você será capaz de compreender e aplicar o padrão de projeto DAO (Data Access Object) para isolar as operações de banco de dados da lógica de negócios, tornando seu código Java mais organizado, modular e fácil de manter.


🏢 O Cenário Prático (Seu Desafio)

Continuando com o nosso servidor de GTA RP! O código que fizemos na aula passada estava todo misturado no método main. Se precisarmos mudar o banco de dados ou adicionar mais regras, vai virar uma bagunça. O seu desafio é aplicar o Padrão DAO para criar uma estrutura profissional de acesso aos dados dos jogadores.


🧠 Fundamentos: A Teoria Traduzida

O padrão DAO serve para separar a persistência de dados (SQL) do resto da aplicação.

  • Modelo (Entity): É a classe que representa a tabela do banco no Java (Ex: Classe Jogador).
  • Interface DAO: Define o contrato (o que o banco pode fazer: salvar, deletar, buscar).
  • Implementação DAO: É a classe que realmente contém o código SQL para executar as ações.

Camadas do Sistema

flowchart TD
    A["Jogo (Main)"] --> B["Interface JogadorDAO"]
    B --> C["Classe JogadorDAOJDBC"]
    C --> D[("Banco de Dados")]

📖 Exemplo Guiado

Vamos organizar o cadastro de jogadores usando o padrão DAO.

📂 Estrutura Inicial de Pastas

Para esta aula, vamos continuar usando o projeto da aula passada. Certifique-se de que o driver h2-2.2.224.jar continua na pasta lib.

gta-dao-projeto/
├── lib/
│   └── h2-2.2.224.jar
└── src/
    └── App.java (pode apagar este arquivo)

Siga os passos para criar os arquivos dentro da pasta src:

  1. Crie a classe de modelo Jogador.java:
public class Jogador {
    private Integer id;
    private String nickname;
    private Double dinheiro;
 
    public Jogador(String nickname, Double dinheiro) {
        this.nickname = nickname;
        this.dinheiro = dinheiro;
    }
 
    // Getters e Setters
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public String getNickname() { return nickname; }
    public Double getDinheiro() { return dinheiro; }
}
  1. Crie a interface JogadorDAO.java:
import java.util.List;
 
public interface JogadorDAO {
    void inserir(Jogador jogador);
    List<Jogador> buscarTodos();
}
  1. Crie a classe de implementação JogadorDAOJDBC.java:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.List;
 
public class JogadorDAOJDBC implements JogadorDAO {
    private String url = "jdbc:h2:mem:gtadb;DB_CLOSE_DELAY=-1";
 
    @Override
    public void inserir(Jogador jogador) {
        try {
            Connection conn = DriverManager.getConnection(url, "sa", "");
            Statement stmt = conn.createStatement();
 
 
            
            // Garante que a tabela existe
            stmt.execute("CREATE TABLE IF NOT EXISTS JOGADORES (id INT AUTO_INCREMENT, nickname VARCHAR(50), dinheiro DOUBLE)");
            
            String sql = "INSERT INTO JOGADORES (nickname, dinheiro) VALUES ('" + 
                         jogador.getNickname() + "', " + jogador.getDinheiro() + ")";
                         
            stmt.executeUpdate(sql);
 
            conn.close();
            System.out.println("Jogador salvo via DAO!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public List<Jogador> buscarTodos() {
        // Implementação simplificada (vimos na aula passada)
        return null; 
    }
}

4. Crie o arquivo TesteDAO.java para testar:

public class TesteDAO {
    public static void main(String[] args) {
        // Criamos o objeto DAO
        JogadorDAO dao = new JogadorDAOJDBC();
        
        // Criamos um jogador
        Jogador j1 = new Jogador("Big Smoke", 500.0);
        
        // Salvamos no banco via DAO
        dao.inserir(j1);
    }
}

🕹️ Como Executar e Testar no VS Code

  1. Abra o arquivo TesteDAO.java.
  2. Clique em Run logo acima do método main.

Resultado Esperado:

Jogador salvo via DAO!


🛠️ Prática Obrigatória 1

Complete o método buscarTodos() na classe JogadorDAOJDBC para que ele retorne uma lista de objetos Jogador lidos do banco de dados. Você deve usar a mesma lógica de consulta da aula passada, mas agora preenchendo objetos e adicionando-os a uma lista.

Resultado Esperado: Ao chamar dao.buscarTodos(), você deve receber uma lista contendo os jogadores cadastrados no banco.


🛠️ Prática Obrigatória 2

Adicione o método void deletar(int id) na interface JogadorDAO e implemente-o na classe JogadorDAOJDBC usando o comando SQL DELETE FROM JOGADORES WHERE id = ?.

Resultado Esperado: O jogador com o ID especificado deve ser removido do banco de dados.


📤 Instruções de Entrega (GitHub Desktop + Microsoft Teams)

Neste curso, você entregará suas atividades enviando o código para o seu repositório no GitHub usando o aplicativo GitHub Desktop. Siga o passo a passo detalhado:

  1. Verifique a estrutura: Certifique-se de que sua estrutura de pastas final está idêntica à mostrada abaixo.
  2. Abra o GitHub Desktop: Certifique-se de que o repositório do seu curso está selecionado no canto superior esquerdo.
  3. Visualize as alterações: Na aba Changes (à esquerda), você verá todos os arquivos que criou ou modificou nesta aula.
  4. Faça o Commit:
    • No campo Summary (na parte inferior esquerda), digite uma mensagem curta descrevendo o que fez, ex: Finaliza atividades do Capítulo 16.
    • Clique no botão azul Commit to main (ou o nome da sua branch).
  5. Envie para the Nuvem (Push): No topo da tela, clique no botão Push origin. Isso enviará seu código do seu computador para o seu perfil no GitHub.
  6. ⚠️ IMPORTANTE (Repositório Público): Para que o professor consiga corrigir, o seu repositório no GitHub DEVE SER PÚBLICO. Repositórios privados não podem ser visualizados por quem não foi convidado.
  7. Como entregar no Microsoft Teams:
    • Copie o link do seu repositório no GitHub (ex: https://github.com/seu-usuario/seu-repositorio).
    • Abra a tarefa correspondente no Microsoft Teams.
    • Clique no botão Adicionar trabalho (ou Add work).
    • Selecione a opção Link no menu lateral.
    • Cole o link do GitHub no campo “Endereço Web” e digite um texto (ex: Meu Repositório) no campo “Texto a ser exibido”.
    • Clique em Anexar.
    • MUITO IMPORTANTE: Clique no botão Entregar (ou Turn in) no canto superior direito para concluir o envio!

📂 Estrutura Final de Pastas

gta-dao-projeto/
├── lib/
│   └── h2-2.2.224.jar
└── src/
    ├── Jogador.java
    ├── JogadorDAO.java
    ├── JogadorDAOJDBC.java
    └── TesteDAO.java (onde você testará o código)

💡 Checkpoint de Lógica

O que você acabou de fazer é aplicar um Padrão de Projeto (Design Pattern). Na vida real, nós nunca colocamos código SQL dentro da interface gráfica ou das regras de negócio. O DAO serve como uma parede de proteção: se amanhã mudarmos de banco de dados, só precisamos criar uma nova classe que implementa a interface!


🔥 Desafio de Fixação (Opcional)

Pesquise sobre PreparedStatement em Java e tente usá-lo no método inserir do seu DAO para evitar ataques de SQL Injection.


🔑 Gabarito de Código/Fórmulas

Prática 1:

// No método buscarTodos:
List<Jogador> lista = new ArrayList<>();
// Código de conexão...
ResultSet rs = stmt.executeQuery("SELECT * FROM JOGADORES");
while(rs.next()) {
    Jogador j = new Jogador(rs.getString("nickname"), rs.getDouble("dinheiro"));
    j.setId(rs.getInt("id"));
    lista.add(j);
}
return lista;

Prática 2:

// Na interface:
void deletar(int id);
 
// Na implementação:
@Override
public void deletar(int id) {
    // Conexão...
    stmt.executeUpdate("DELETE FROM JOGADORES WHERE id = " + id);
}

Desafio:

// Exemplo com PreparedStatement:
String sql = "INSERT INTO JOGADORES (nickname, dinheiro) VALUES (?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, jogador.getNickname());
pstmt.setDouble(2, jogador.getDinheiro());
pstmt.executeUpdate();

Capitulo Anterior | Proximo Capitulo