Criar o Projeto Spring Boot

Você pode criar um novo projeto Spring Boot usando o Spring Initializr:

  1. Configure o projeto:
    • Project: Maven
    • Language: Java
    • Spring Boot Version: Última versão estável
    • Group: com.livraria
    • Artifact: livraria
    • Package Name: com.livraria
    • Packaging: Jar
    • Java Version: 17 ou superior
    • Dependências:
      • Spring Web (para criar a API REST)
      • Spring Data JPA (para integração com Hibernate)
      • JDBC API (para comunicação direta com o banco)
      • H2 Database (banco de dados em memória para testes)
  2. Clique em Generate e extraia o arquivo .zip em sua máquina.

Estrutura de Arquivos

Após importar o projeto em sua IDE (IntelliJ, Eclipse, VSCode), a estrutura de pastas será:


Configurar o Banco de Dados

No arquivo application.properties, configure o banco H2:

Acesse o console H2 em: http://localhost:8080/h2-console/ e use o JDBC URL jdbc:h2:mem:livraria.


Criar a Entidade Livro

No contexto do Spring Boot e do Hibernate, uma entidade é uma classe Java que representa uma tabela no banco de dados. Essa classe é anotada com @Entity, e cada um de seus atributos corresponde a uma coluna da tabela.

  • @Entity: Indica que esta classe será gerenciada pelo JPA e mapeada para uma tabela no banco de dados.
  • @Table(name = "livros"): Define o nome da tabela no banco de dados. Se não for especificado, a tabela assumirá o nome da classe (Livro).

A entidade Livro será usada para armazenar informações sobre livros na livraria, como título, autor e preço.

  • @Id: Define a chave primária da entidade.
  • @GeneratedValue(strategy = GenerationType.IDENTITY): Indica que o banco de dados será responsável por gerar automaticamente o valor do ID (auto incremento).

O uso do GenerationType.IDENTITY é comum para bancos como MySQL e PostgreSQL, que suportam colunas AUTO_INCREMENT.

private String titulo;
private String autor;
private Double preco;

Esses são os atributos que representam as colunas do banco de dados. Cada instância da classe Livro representa uma linha na tabela livros.

Por padrão, atributos simples como String e Double são mapeados automaticamente para colunas do banco de dados com os mesmos nomes.

Crie a classe Livro.java dentro da pasta model:

package com.livraria.model;

import jakarta.persistence.*;

@Entity
@Table(name = "livros")
public class Livro {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String titulo;
private String autor;
private Double preco;

public Livro() {}

public Livro(String titulo, String autor, Double preco) {
this.titulo = titulo;
this.autor = autor;
this.preco = preco;
}

// Getters e Setters
}

Criar o Repositório

No Spring Data JPA, um repositório é uma interface que fornece métodos para manipulação de dados no banco de maneira simples e eficiente. Ele serve como uma camada de abstração entre a aplicação e o banco de dados, eliminando a necessidade de escrever consultas SQL manualmente.

A anotação @Repository indica que essa interface será gerenciada pelo Spring como um componente de repositório, permitindo a injeção de dependências em outras classes.

Embora essa anotação seja opcional, é uma boa prática incluí-la para tornar o código mais legível e garantir que o Spring reconheça o repositório como um bean.

Com a extensão da classe JpaRepository , evitamos a necessidade de escrever código repetitivo para operações básicas no banco de dados:

  • JpaRepository<Livro, Long> significa que estamos criando um repositório para a entidade Livro, onde:
    • Livro é a classe da entidade gerenciada.
    • Long é o tipo do identificador (ID) da entidade.

A interface JpaRepository já fornece métodos CRUD padrão, como:

  • save(Livro livro): Salva um novo livro ou atualiza um existente.
  • findById(Long id): Busca um livro pelo ID.
  • findAll(): Retorna todos os livros da tabela.
  • deleteById(Long id): Exclui um livro pelo ID.

Crie a interface LivroRepository.java dentro da pasta repository:

package com.livraria.repository;

import com.livraria.model.Livro;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface LivroRepository extends JpaRepository<Livro, Long> {
}

Criar o Serviço

A camada de serviço é responsável por conter a lógica de negócios da aplicação. Diferente do repositório, que apenas interage com o banco de dados, o serviço processa os dados antes de enviá-los ao controlador (Controller).

A principal vantagem de utilizar um serviço é separar responsabilidades dentro da aplicação. Isso segue o princípio SRP (Single Responsibility Principle) da arquitetura SOLID, tornando o código mais organizado e facilitando a manutenção.

A anotação @Service indica que essa classe pertence à camada de serviço da aplicação. O Spring gerencia automaticamente essa classe, permitindo que ela seja injetada em outras partes do código.

Com o @Autowired, o LivroRepository é injetado automaticamente no serviço pelo Spring Dependency Injection. Isso evita a necessidade de criar instâncias manualmente usando new, deixando a aplicação mais flexível

MétodoO que faz?
listarTodos()Retorna todos os livros do banco de dados.
buscarPorId(id)Retorna um livro específico pelo ID.
salvar(livro)Salva um novo livro ou atualiza um existente.
atualizar(id, livro)Atualiza um livro existente, se o ID for válido.
deletar(id)Remove um livro do banco de dados pelo ID.

Por que usar uma camada de serviço?

Separa a lógica de negócios do controlador.
Melhora a organização e reusabilidade do código.
Facilita a manutenção e testes unitários

Crie a classe LivroService.java dentro da pasta service:

package com.livraria.service;

import com.livraria.model.Livro;
import com.livraria.repository.LivroRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class LivroService {

    @Autowired
    private LivroRepository livroRepository;

    public List<Livro> listarTodos() {
        return livroRepository.findAll();
    }

    public Livro salvar(Livro livro) {
        return livroRepository.save(livro);
    }

    public void deletar(Long id) {
        livroRepository.deleteById(id);
    }
}

Criar o Controller

A anotação @RestController indica que esta classe é um Controller REST, ou seja, ela retorna respostas no formato JSON.

@RequestMapping("/livros") define que todas as requisições desta classe começarão com /livros.
Exemplo:

  • GET /livros → Retorna todos os livros
  • GET /livros/1 → Retorna o livro com ID 1

Os métodos HTTP (ou verbos HTTP) definem as ações que podem ser executadas em um servidor web. Eles são essenciais para a comunicação entre o cliente (frontend, Postman, etc.) e o servidor (API REST, banco de dados, etc.).

Método HTTPDescriçãoUso na API REST
GETRecupera dados do servidor.Buscar um ou mais registros.
POSTEnvia dados para o servidor.Criar um novo registro.
PUTAtualiza um recurso existente.Modificar um registro por completo.
PATCHAtualiza parcialmente um recurso.Alterar apenas alguns campos de um registro.
DELETERemove um recurso do servidor.Excluir um registro.

Por que usar um Controller?

Permite interagir com a API via HTTP.
Separa as responsabilidades (Controller não lida com lógica de negócios).
Retorna respostas HTTP adequadas (200, 201, 404, 204)

MétodoObjetivoExemplo de EndpointQuando Usar?
GETBuscar informaçõesGET /livrosQuando precisar recuperar dados do servidor.
POSTCriar um novo recursoPOST /livrosQuando precisar criar um novo livro.
PUTAtualizar um recurso completoPUT /livros/1Quando precisar modificar todos os campos de um livro.
PATCHAtualizar parcialmente um recursoPATCH /livros/1Quando precisar modificar apenas alguns campos.
DELETERemover um recursoDELETE /livros/1Quando precisar excluir um livro do banco de dados.

Crie a classe LivroController.java dentro da pasta controller:

package com.livraria.controller;

import com.livraria.model.Livro;
import com.livraria.service.LivroService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/livros")
public class LivroController {

@Autowired
private LivroService livroService;

@GetMapping
public List<Livro> listarLivros() {
return livroService.listarTodos();
}

@PostMapping
public Livro adicionarLivro(@RequestBody Livro livro) {
return livroService.salvar(livro);
}

@DeleteMapping("/{id}")
public void removerLivro(@PathVariable Long id) {
livroService.deletar(id);
}
}

Testar a API

Rodar o projeto na sua IDE ou via terminal com:

mvn spring-boot:run

Agora, você pode testar os endpoints com o Postman ou CURL:

  • Listar Livros
curl -X GET http://localhost:8080/livros
  • Adicionar um Livro
curl -X POST http://localhost:8080/livros -H "Content-Type: application/json" -d '{"titulo": "O Senhor dos Anéis", "autor": "J.R.R. Tolkien", "preco": 99.90}'
  • Remover um Livro
curl -X DELETE http://localhost:8080/livros/1

Arquitetura Utilizada

O projeto segue a arquitetura em camadas:

  1. Controller: Responsável por receber as requisições HTTP e chamar os serviços.
  2. Service: Camada intermediária, onde fica a lógica de negócios.
  3. Repository: Interface que lida com a persistência no banco de dados via JPA.
  4. Model: Define as entidades e suas tabelas no banco de dados.

Além disso, usamos o Spring Boot, que facilita a configuração e inicialização do projeto, e o Spring Data JPA, que abstrai operações com banco de dados.


Conclusão

Esse foi um guia para iniciar um projeto Spring Boot com um módulo de livraria. Você pode expandi-lo adicionando autenticação, mais entidades (ex: clientes, pedidos) e um banco de dados real como PostgreSQL ou MySQL.

Conteúdos