🚀 Capítulo 18: Camadas do Spring e JPA
🎯 Objetivo da Aula
Ao final desta aula, você será capaz de organizar uma aplicação Spring Boot no padrão de Camadas (Controller, Service, Repository) e utilizar o Spring Data JPA para salvar e buscar dados no banco H2 sem precisar escrever código SQL manualmente.
🏢 O Cenário Prático (Seu Desafio)
Você é o operador Tank a bordo da Nabucodonosor. O seu desafio é criar um sistema seguro para gerenciar o cadastro dos tripulantes e rebeldes da resistência de Zion. Você deve salvar os dados (Nome, Codinome e Status) em um banco de dados e organizar o código em camadas profissionais para que os Agentes da Matrix não consigam quebrar o sistema!
🧠 Fundamentos: A Teoria Traduzida
Em projetos reais, não colocamos todo o código em um arquivo só. Nós dividimos em camadas para manter o código organizado e fácil de manter:
- Controller: É a porta de entrada. Recebe as requisições web (HTTP) e devolve as respostas (geralmente em JSON).
- Service: É o cérebro. Contém as regras de negócio (ex: “não pode cadastrar rebeldes com codinomes duplicados”).
- Repository: É o braço que mexe no banco de dados.
- JPA / Hibernate: É uma tecnologia que transforma objetos Java em tabelas no banco automaticamente. Você não precisa escrever
INSERTouSELECT!
Arquitetura em Camadas
flowchart TD A["Cliente (Navegador/Postman)"] -->|Requisição HTTP| B["Controller"] B --> C["Service"] C --> D["Repository"] D --> E[("Banco H2")]
📖 Exemplo Guiado
Vamos criar a estrutura para gerenciar os rebeldes de Zion.
🛠️ Passo a Passo para Criar o Projeto no VS Code
- Abra o VS Code.
- Pressione as teclas
Ctrl + Shift + P. - Digite
Spring Initializr: Create Maven Projecte pressioneEnter. - Selecione a versão estável do Spring Boot e a linguagem
Java. - Digite o Group ID:
com.matrixe o Artifact ID:zion. - Selecione a versão do Java instalada na sua máquina.
- Dependências (MUITO IMPORTANTE): Busque e adicione estas 3 dependências:
Spring Web,Spring Data JPAeH2 Database. Pressione Enter para confirmar. - Escolha a pasta e abra o projeto.
📂 Estrutura Inicial de Pastas (Maven)
zion/
├── src/
│ └── main/
│ ├── java/
│ │ └── com/matrix/zion/
│ │ └── ZionApplication.java
│ └── resources/
│ └── application.properties
└── pom.xmlSiga os passos para criar os arquivos dentro da pasta com/matrix/zion/:
- Crie a classe de modelo
Rebelde.java(a nossa entidade de banco):
package com.matrix.zion;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity // Diz ao Spring que essa classe vira uma tabela no banco
public class Rebelde {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nome;
private String codinome;
// Construtores (Obrigatório ter o vazio para o JPA)
public Rebelde() {}
public Rebelde(String nome, String codinome) { this.nome = nome; this.codinome = codinome; }
// Getters e Setters
public Long getId() { return id; }
public String getNome() { return nome; }
public String getCodinome() { return codinome; }
}- Crie a interface
RebeldeRepository.java(acesso aos dados):
package com.matrix.zion;
import org.springframework.data.jpa.repository.JpaRepository;
// O JpaRepository já vem com métodos prontos como save() e findAll()!
public interface RebeldeRepository extends JpaRepository<Rebelde, Long> {
}- Crie a classe
RebeldeService.java(regras de negócio):
package com.matrix.zion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service // Diz que essa classe é a camada de serviço
public class RebeldeService {
@Autowired // O Spring cria e injeta o objeto automaticamente
private RebeldeRepository repository;
public List<Rebelde> listarTodos() {
return repository.findAll();
}
public Rebelde salvar(Rebelde rebelde) {
return repository.save(rebelde);
}
}- Crie a classe
RebeldeController.java(atendimento Web):
package com.matrix.zion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class PokemonController {
@Autowired
private RebeldeService service;
@GetMapping("/rebeldes")
public List<Rebelde> listar() {
return service.listarTodos();
}
@PostMapping("/rebeldes")
public Rebelde criar(@RequestBody Rebelde rebelde) {
return service.salvar(rebelde);
}
}🕹️ Como Executar e Testar no VS Code
- Abra o arquivo
ZionApplication.java. - Clique em Run logo acima do método
main. - Abra o navegador e acesse:
http://localhost:8080/rebeldes.
Resultado Esperado:
Você verá uma lista vazia [] (se o banco acabou de subir) ou os rebeldes cadastrados em formato JSON.
Para cadastrar um rebelde, você pode usar uma extensão como o Thunder Client no VS Code para enviar uma requisição POST para http://localhost:8080/rebeldes com o corpo (Body) em formato JSON:
{
"nome": "Neo",
"codinome": "The One"
}🛠️ Prática Obrigatória 1
No arquivo src/main/resources/application.properties, adicione as configurações para habilitar o console web do banco H2:
spring.h2.console.enabled=true
spring.h2.console.path=/h2-consoleRode o projeto, acesse http://localhost:8080/h2-console no seu navegador e veja a tabela REBELDE criada automaticamente pelo JPA!
🛠️ Prática Obrigatória 2
Crie um novo método no RebeldeService e no RebeldeController para buscar um Rebelde pelo seu ID (utilizando o método repository.findById(id)).
📤 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:
- Verifique a estrutura: Certifique-se de que sua estrutura de pastas final está idêntica à mostrada abaixo.
- Abra o GitHub Desktop: Certifique-se de que o repositório do seu curso está selecionado no canto superior esquerdo.
- Visualize as alterações: Na aba Changes (à esquerda), você verá todos os arquivos que criou ou modificou nesta aula.
- 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 18. - Clique no botão azul Commit to main (ou o nome da sua branch).
- No campo Summary (na parte inferior esquerda), digite uma mensagem curta descrevendo o que fez, ex:
- Envie para a 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.
- ⚠️ 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.
- 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!
- Copie o link do seu repositório no GitHub (ex:
📂 Estrutura Final de Pastas
zion/
├── src/
│ └── main/
│ ├── java/
│ │ └── com/matrix/zion/
│ │ ├── ZionApplication.java
│ │ ├── Rebelde.java
│ │ ├── RebeldeRepository.java
│ │ ├── RebeldeService.java
│ │ └── RebeldeController.java
│ └── resources/
│ └── application.properties
└── pom.xml💡 Checkpoint de Lógica
O que você acabou de fazer é o padrão de mercado (Enterprise Pattern). Dividir em camadas garante que se amanhã mudarmos a forma de acessar o banco, as regras de negócio e a Web continuam funcionando intactas!
🔥 Desafio de Fixação (Opcional)
Pesquise como criar um método de busca por codinome no Repository usando as convenções de nome do Spring Data (ex: List<Rebelde> findByCodinome(String codinome)).
🔑 Gabarito de Código/Fórmulas
Prática 1:
(Basta adicionar as linhas no arquivo de propriedades).
Prática 2:
No Controller:
@GetMapping("/rebeldes/{id}")
public Rebelde buscar(@PathVariable Long id) {
return service.buscarPorId(id); // Você deve criar este método no Service também!
}Desafio:
No Repository, basta declarar o método (sem implementar!):
public interface RebeldeRepository extends JpaRepository<Rebelde, Long> {
List<Rebelde> findByCodinome(String codinome);
}