0% acharam este documento útil (0 voto)
22 visualizações53 páginas

Manual Da API Spring Boot

O manual detalha a estrutura e funcionamento da API Spring Boot para um sistema de comércio, abordando suas camadas, como modelos, repositórios, serviços e controladores. Ele também fornece instruções sobre como executar a API, incluindo pré-requisitos, configuração do banco de dados e acesso aos endpoints. Além disso, descreve as entidades principais, como Uf, Sexo, Cidade e Cep, com seus atributos e relacionamentos.

Enviado por

estremot
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
22 visualizações53 páginas

Manual Da API Spring Boot

O manual detalha a estrutura e funcionamento da API Spring Boot para um sistema de comércio, abordando suas camadas, como modelos, repositórios, serviços e controladores. Ele também fornece instruções sobre como executar a API, incluindo pré-requisitos, configuração do banco de dados e acesso aos endpoints. Além disso, descreve as entidades principais, como Uf, Sexo, Cidade e Cep, com seus atributos e relacionamentos.

Enviado por

estremot
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

Manual da API Spring Boot – Estudo de Caso (Comércio)

Professor: Marcos Antonio Estremote

Fatec Dr. José Camargo Jales - 2025


Introdução
Este manual detalha a estrutura e o funcionamento da API Spring Boot
desenvolvida, abordando seus principais componentes, desde as entidades de dados
até os controladores que expõem os endpoints.

Arquitetura da API
A API segue uma arquitetura em camadas, comumente utilizada em aplicações
Spring Boot, compreendendo:
• Modelos (Entidades): Representam os dados da aplicação e são mapeadas
para tabelas no banco de dados.
• Repositórios: Camada de acesso a dados, responsável pela comunicação com o
banco de dados para operações CRUD (Create, Read, Update, Delete).
• Serviços: Camada de lógica de negócios, onde as regras e operações mais
complexas são implementadas, utilizando os repositórios para interagir com os
dados.
• Controladores: Camada de apresentação, responsável por expor os endpoints
da API, receber requisições HTTP, interagir com os serviços e retornar
respostas.
• Formulários (DTOs): Objetos de Transferência de Dados utilizados para
transportar dados entre as camadas, especialmente entre os controladores e os
serviços, e para validar entradas.
• Configurações: Classes de configuração, como a configuração de CORS, para
definir o comportamento da aplicação.

Componentes da API
1. Entidades (Models)
As entidades representam os objetos de domínio da aplicação.

2. Repositórios (Repositories)
Os repositórios são interfaces que estendem JpaRepository do Spring Data
JPA, fornecendo métodos para interagir com o banco de dados.
3. Serviços (Services)
Os serviços contêm a lógica de negócios da aplicação.

4. Formulários (Forms/DTOs)
Os formulários são utilizados para receber e validar dados de entrada nas
requisições.

5. Controladores (Controllers)
Os controladores gerenciam as requisições HTTP e as respostas da API.

6. Configurações (Configuration)
Arquivos de configuração da aplicação.

Como Executar a API (Considerações Gerais)


Para executar esta API Spring Boot, geralmente são necessários os seguintes
passos (detalhes específicos podem variar dependendo do ambiente de
desenvolvimento):
1. Pré-requisitos:
– Java Development Kit (JDK) instalado (versão compatível com o
projeto).
– Maven ou Gradle instalado (gerenciador de dependências utilizado no
projeto).
– Um Sistema de Gerenciamento de Banco de Dados (SGBD) compatível e
configurado (ex: PostgreSQL, MySQL, H2).
2. Configuração do Banco de Dados:
– As propriedades de conexão com o banco de dados (URL, usuário,
senha, driver) devem estar configuradas no arquivo
application.properties ou application.yml do projeto Spring Boot.
3. Build do Projeto:
– Navegue até o diretório raiz do projeto via terminal.
– Execute o comando de build (ex: mvn clean install para Maven ou
gradle build para Gradle).
4. Execução da Aplicação:
– Após o build bem-sucedido, execute a aplicação. Isso pode ser feito de
várias maneiras:
• Através da sua IDE (Eclipse, IntelliJ IDEA) clicando com o botão
direito na classe principal da aplicação (geralmente anotada com
@SpringBootApplication) e selecionando “Run As Java
Application”.
• Via terminal, navegando até o diretório target (para Maven) ou
build/libs (para Gradle) e executando o arquivo JAR gerado:
java -jar nome-do-arquivo.jar.
5. Acesso à API:
– Uma vez que a aplicação esteja rodando, os endpoints definidos nos
controladores estarão acessíveis através de um cliente HTTP (como
Postman, Insomnia, ou o próprio navegador para requisições GET)
utilizando a URL base (normalmente http://localhost:8080, a menos
que a porta tenha sido alterada) seguida pelo caminho do endpoint (ex:
http://localhost:8080/ufs).

Este manual prosseguirá com a explicação detalhada de cada componente da


API.

1.1. Entidade Uf.java


A classe Uf é uma entidade JPA (Java Persistence API) que representa uma
Unidade Federativa (Estado) no sistema. Ela é mapeada para uma tabela no banco de
dados e seus atributos correspondem às colunas dessa tabela.
package com.fatec.comercio.models;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Uf {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer coduf;

@Column
private String nomeuf;

@Column
private String sigla;

@OneToMany(mappedBy="uf")
private java.util.List<Cidade> cidades;

public Integer getCoduf() {


return coduf;
}

public String getNomeuf() {


return nomeuf;
}

public String getSigla() {


return sigla;
}

public void setCoduf(Integer coduf) {


this.coduf = coduf;
}

public void setNomeuf(String nomeuf) {


this.nomeuf = nomeuf;
}

public void setSigla(String sigla) {


this.sigla = sigla;
}
}

Anotações Utilizadas:
• @Entity: Marca esta classe como uma entidade JPA, indicando que ela
representa uma tabela no banco de dados.
• @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) :
Usada pela biblioteca Jackson (para serialização/desserialização JSON) para
ignorar propriedades específicas que podem causar problemas durante a
serialização, especialmente em contextos de lazy loading do Hibernate.
hibernateLazyInitializer e handler são propriedades injetadas pelo
Hibernate para gerenciar o carregamento tardio de associações.
• @Id: Especifica que o atributo coduf é a chave primária da entidade.
• @GeneratedValue(strategy = GenerationType.AUTO): Configura a forma
como a chave primária é gerada. GenerationType.AUTO permite que o
provedor de persistência (Hibernate, neste caso) escolha a estratégia mais
apropriada (geralmente uma sequência ou uma coluna de auto incremento no
banco de dados).
• @Column: Embora não seja estritamente necessário para atributos simples (o
JPA pode inferi-los), pode ser usado para especificar detalhes da coluna, como
nome, nulidade, tamanho, etc. Aqui, é usado implicitamente para nomeuf e
sigla.
• @OneToMany(mappedBy="uf"): Define um relacionamento um-para-muitos
entre Uf e Cidade. Uma UF pode ter muitas cidades. O atributo mappedBy="uf"
indica que o lado Cidade da relação é o proprietário do relacionamento, e o
mapeamento é feito pelo atributo uf na classe Cidade. Isso significa que a
tabela Cidade terá uma chave estrangeira referenciando a UF.
Atributos:
• private Integer coduf: Representa o código identificador único da UF. É a
chave primária da tabela.
• private String nomeuf: Armazena o nome completo da Unidade Federativa
(ex: “São Paulo”).
• private String sigla: Armazena a sigla da Unidade Federativa (ex: “SP”).
• private java.util.List<Cidade> cidades: Representa a lista de cidades que
pertencem a esta UF. Este é o lado “muitos” do relacionamento OneToMany com
a entidade Cidade.
Métodos:
A classe Uf possui os métodos getters e setters padrão para todos os seus
atributos (coduf, nomeuf, sigla). Estes métodos permitem o acesso e a modificação
dos valores dos atributos da entidade:
• getCoduf(): Retorna o código da UF.
• setNomeuf(String nomeuf): Define o nome da UF.
• getNomeuf(): Retorna o nome da UF.
• setSigla(String sigla): Define a sigla da UF.
• getSigla(): Retorna a sigla da UF.
• setCoduf(Integer coduf): Define o código da UF.

Não há construtores explícitos definidos, então um construtor padrão (sem


argumentos) é fornecido implicitamente pelo Java, o que é um requisito para
entidades JPA. O relacionamento com Cidade é gerenciado através da anotação
@OneToMany, e a lista cidades será populada pelo provedor JPA quando as cidades
associadas a uma UF forem carregadas do banco de dados.

1.2. Entidade Sexo.java


A classe Sexo é outra entidade JPA que representa o sexo de um indivíduo no
sistema. Assim como Uf, ela é mapeada para uma tabela no banco de dados.
package com.fatec.comercio.models;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Sexo {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer codsexo;

@Column
private String nomesexo;

public void setCodsexo(Integer codsexo) {


this.codsexo = codsexo;
}

public void setNomesexo(String nomesexo) {


this.nomesexo = nomesexo;
}

public Integer getCodsexo() {


return codsexo;
}

public String getNomesexo() {


return nomesexo;
}
}

Anotações Utilizadas:
• @Entity: Designa esta classe como uma entidade JPA, indicando seu
mapeamento para uma tabela de banco de dados.
• @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) :
Similar à entidade Uf, esta anotação instrui o Jackson a ignorar propriedades
específicas do Hibernate durante a serialização JSON, prevenindo problemas
com lazy loading.
• @Id: Marca o atributo codsexo como a chave primária da entidade Sexo.
• @GeneratedValue(strategy = GenerationType.AUTO): Configura a geração
automática da chave primária codsexo, permitindo que o provedor de
persistência determine a melhor estratégia (como auto incremento ou
sequence).
• @Column: Usada implicitamente para o atributo nomesexo, indicando que ele
será mapeado para uma coluna na tabela Sexo.
Atributos:
• private Integer codsexo: O identificador único para cada registro de sexo.
Funciona como a chave primária.
• private String nomesexo: Armazena a descrição do sexo (ex: “Masculino”,
“Feminino”, “Outro”).
Métodos:
A classe Sexo fornece os métodos getters e setters padrão para seus atributos:
• getCodsexo(): Retorna o código do sexo.
• setCodsexo(Integer codsexo): Define o código do sexo.
• getNomesexo(): Retorna o nome/descrição do sexo.
• setNomesexo(String nomesexo): Define o nome/descrição do sexo.

Assim como a entidade Uf, a classe Sexo não possui construtores explícitos,
utilizando o construtor padrão fornecido pelo Java, que é uma exigência para
entidades JPA. Esta entidade é mais simples, não possuindo relacionamentos diretos
com outras entidades neste trecho de código, servindo como uma tabela de lookup
para os possíveis valores de sexo que podem ser associados a outras entidades no
sistema (por exemplo, um cliente ou usuário).
1.3. Entidade Cidade.java
A classe Cidade representa uma cidade dentro do sistema e está
intrinsecamente ligada a uma Unidade Federativa ( Uf). É uma entidade JPA mapeada
para uma tabela no banco de dados.
package com.fatec.comercio.models;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Cidade {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer codcidade;

@Column
private String nomecidade;

@ManyToOne
@JoinColumn(name = "coduffk")
private Uf uf;

public Integer getCodcidade() {


return codcidade;
}

public String getNomecidade() {


return nomecidade;
}

public Uf getUf() {
return uf;
}

public void setCodcidade(Integer codcidade) {


this.codcidade = codcidade;
}

public void setNomecidade(String nomecidade) {


this.nomecidade = nomecidade;
}

public void setUf(Uf uf) {


this.uf = uf;
}

public Cidade(String nomecidade, Uf uf) {


this.nomecidade = nomecidade;
this.uf = uf;
}

public Cidade() {
}
}

Anotações Utilizadas:
• @Entity: Define Cidade como uma entidade JPA, indicando que será persistida
no banco de dados.
• @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) :
Similar às entidades anteriores, esta anotação é usada pelo Jackson para evitar
problemas de serialização com propriedades do Hibernate relacionadas ao lazy
loading.
• @Id: Marca codcidade como a chave primária da entidade.
• @GeneratedValue(strategy = GenerationType.AUTO): Configura a geração
automática da chave primária codcidade.
• @Column: Usada implicitamente para nomecidade, mapeando-o para uma
coluna na tabela Cidade.
• @ManyToOne: Define um relacionamento muitos-para-um entre Cidade e Uf.
Muitas cidades podem pertencer a uma única UF. Este é o lado proprietário do
relacionamento.
• @JoinColumn(name = "coduffk"): Especifica a coluna no banco de dados que
atuará como chave estrangeira para o relacionamento com Uf. A coluna na
tabela Cidade que armazena o ID da UF será nomeada coduffk.
Atributos:
• private Integer codcidade: O identificador único para cada cidade, atuando
como chave primária.
• private String nomecidade: Armazena o nome da cidade (ex: “Campinas”).
• private Uf uf: Representa a Unidade Federativa à qual a cidade pertence.
Este atributo estabelece o vínculo com a entidade Uf.
Construtores:
A classe Cidade possui dois construtores explícitos:
• public Cidade(String nomecidade, Uf uf): Um construtor parametrizado
que permite criar uma instância de Cidade fornecendo diretamente o nome da
cidade e o objeto Uf associado. Isso é útil para criar novas cidades já vinculadas
a uma UF.
• public Cidade(): Um construtor padrão (sem argumentos). Este construtor é
essencial para o funcionamento do JPA, que o utiliza para instanciar objetos da
entidade ao recuperá-los do banco de dados.
Métodos:
A classe Cidade inclui os métodos getters e setters padrão para todos os seus
atributos (codcidade, nomecidade, uf):
• getCodcidade(): Retorna o código da cidade.
• setCodcidade(Integer codcidade): Define o código da cidade.
• getNomecidade(): Retorna o nome da cidade.
• setNomecidade(String nomecidade): Define o nome da cidade.
• getUf(): Retorna o objeto Uf associado à cidade.
• setUf(Uf uf): Define o objeto Uf associado à cidade.

O relacionamento @ManyToOne com Uf é um aspecto crucial desta entidade, pois


estabelece a hierarquia geográfica onde cada cidade está contida em uma UF. A
anotação @JoinColumn garante que a chave estrangeira seja corretamente mapeada no
banco de dados, permitindo que o JPA gerencie essa associação.

1.4. Entidade Cep.java


A classe Cep é uma entidade JPA que representa um Código de Endereçamento
Postal (CEP) no sistema. Ela é mapeada para uma tabela no banco de dados e
armazena informações sobre os CEPs.
package com.fatec.comercio.models;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Cep {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer codcep;

@Column
private String numerocep;

public Integer getCodcep() {


return codcep;
}

public String getNumerocep() {


return numerocep;
}

public void setCodcep(Integer codcep) {


this.codcep = codcep;
}

public void setNumerocep(String numerocep) {


this.numerocep = numerocep;
}
}

Anotações Utilizadas:
• @Entity: Marca esta classe como uma entidade JPA, indicando que ela
representa uma tabela no banco de dados.
• @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) :
Utilizada pela biblioteca Jackson para ignorar propriedades específicas do
Hibernate durante a serialização JSON, o que é útil para evitar problemas com o
carregamento tardio (lazy loading).
• @Id: Especifica que o atributo codcep é a chave primária da entidade Cep.
• @GeneratedValue(strategy = GenerationType.AUTO): Configura a forma
como a chave primária codcep é gerada. A estratégia GenerationType.AUTO
permite que o provedor de persistência (Hibernate) escolha a estratégia mais
apropriada, como uma sequência ou uma coluna de auto incremento.
• @Column: Usada implicitamente para o atributo numerocep, indicando que ele
será mapeado para uma coluna na tabela Cep.
Atributos:
• private Integer codcep: Representa o código identificador único do CEP. É a
chave primária da tabela.
• private String numerocep: Armazena o número do CEP (ex: “13083-852”).

Métodos:
A classe Cep possui os métodos getters e setters padrão para todos os seus
atributos (codcep, numerocep). Estes métodos permitem o acesso e a modificação dos
valores dos atributos da entidade:
• getCodcep(): Retorna o código do CEP.
• setCodcep(Integer codcep): Define o código do CEP.
• getNumerocep(): Retorna o número do CEP.
• setNumerocep(String numerocep): Define o número do CEP.

Semelhante à entidade Sexo, a classe Cep é uma entidade relativamente


simples, sem relacionamentos diretos com outras entidades neste trecho de código.
Ela serve como uma tabela para armazenar os CEPs que podem ser utilizados em
outras partes do sistema, por exemplo, em endereços de clientes ou fornecedores. A
ausência de construtores explícitos implica o uso do construtor padrão (sem
argumentos) fornecido pelo Java, o que é um requisito para entidades JPA.

1.5. Entidade Bairro.java


A classe Bairro é uma entidade JPA que representa um bairro no sistema. Ela é
mapeada para uma tabela no banco de dados e armazena informações sobre os
bairros. Uma característica notável desta entidade é a presença da anotação
@CrossOrigin diretamente na classe, o que sugere uma configuração específica de
Cross-Origin Resource Sharing (CORS) para esta entidade, embora a configuração
global de CORS seja geralmente gerenciada em uma classe de configuração separada
(como CorsConfig.java).
package com.fatec.comercio.models;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMethod;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@CrossOrigin(
origins = "http://localhost:4200",
methods = { RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT,
RequestMethod.DELETE },
allowedHeaders = "*",
maxAge = 3600 // Tempo de cache do CORS (em segundos)
)
public class Bairro {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer codbairro;

@Column
private String nomebairro;

public Integer getCodbairro() {


return codbairro;
}

public String getNomebairro() {


return nomebairro;
}

public void setCodbairro(Integer codbairro) {


this.codbairro = codbairro;
}

public void setNomebairro(String nomebairro) {


this.nomebairro = nomebairro;
}
}

Anotações Utilizadas:
• @Entity: Designa esta classe como uma entidade JPA, indicando seu
mapeamento para uma tabela de banco de dados.
• @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) :
Instrução para a biblioteca Jackson ignorar propriedades específicas do
Hibernate durante a serialização JSON, útil para evitar problemas com lazy
loading.
• @CrossOrigin(...): Esta anotação é usada para configurar o CORS
diretamente no nível da entidade ou, mais comumente, em controladores. Aqui,
ela está configurada para permitir requisições da origem
http://localhost:4200 (provavelmente uma aplicação frontend Angular),
para os métodos HTTP GET, POST, PUT, DELETE, permitindo todos os
cabeçalhos (allowedHeaders = "*") e definindo um tempo de cache para as
respostas preflight de CORS de 3600 segundos (maxAge = 3600). É importante
notar que, embora funcional, aplicar @CrossOrigin em entidades JPA não é a
prática mais comum; geralmente, é aplicada em classes @RestController ou
configurada globalmente.
• @Id: Marca o atributo codbairro como a chave primária da entidade Bairro.
• @GeneratedValue(strategy = GenerationType.AUTO): Configura a geração
automática da chave primária codbairro, permitindo que o provedor de
persistência escolha a estratégia apropriada.
• @Column: Usada implicitamente para o atributo nomebairro, indicando que ele
será mapeado para uma coluna na tabela Bairro.
Atributos:
• private Integer codbairro: O identificador único para cada registro de
bairro. Funciona como a chave primária.
• private String nomebairro: Armazena o nome do bairro (ex: “Centro”, “Vila
Mariana”).
Métodos:
A classe Bairro fornece os métodos getters e setters padrão para seus
atributos:
• getCodbairro(): Retorna o código do bairro.
• setCodbairro(Integer codbairro): Define o código do bairro.
• getNomebairro(): Retorna o nome do bairro.
• setNomebairro(String nomebairro): Define o nome do bairro.

Assim como as entidades Sexo e Cep, a classe Bairro é uma entidade simples
sem relacionamentos diretos explícitos com outras entidades neste trecho de código.
Ela serve para armazenar informações sobre bairros, que podem ser associados a
outras entidades (como endereços) em diferentes partes do sistema. A ausência de
construtores explícitos indica o uso do construtor padrão Java, necessário para JPA.

2.1. Repositório UfRepository.java


A interface UfRepository é responsável pela camada de acesso aos dados para
a entidade Uf. Ela estende JpaRepository, uma interface do Spring Data JPA que
fornece implementações prontas para operações CRUD (Create, Read, Update, Delete)
e outras funcionalidades comuns de persistência, como paginação e ordenação, sem a
necessidade de escrever código boilerplate.
package com.fatec.comercio.repository;

// Imports omitidos para brevidade, mas incluiriam java.util.List,


org.springframework.data.jpa.repository.JpaRepository, etc.
import com.fatec.comercio.models.Uf;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UfRepository extends JpaRepository<Uf, Integer> {

public Uf findByCoduf(Integer id);


public Uf findByNomeuf(String nomeuf);

Declaração da Interface:
• public interface UfRepository extends JpaRepository<Uf, Integer> :
– public interface UfRepository: Declara uma interface pública
chamada UfRepository.
– extends JpaRepository<Uf, Integer>: Esta é a parte crucial. Ao
estender JpaRepository, a interface UfRepository herda uma série de
métodos para interagir com a entidade Uf.
• O primeiro parâmetro genérico, Uf, especifica a entidade que
este repositório gerenciará.
• O segundo parâmetro genérico, Integer, especifica o tipo da
chave primária da entidade Uf (que é coduf, do tipo Integer).
Métodos Herdados (Exemplos Comuns de JpaRepository):
Ao estender JpaRepository, UfRepository automaticamente disponibiliza
métodos como:
• save(Uf entity): Salva ou atualiza uma entidade Uf.
• findById(Integer id): Busca uma Uf pelo seu ID (retorna um Optional<Uf>).
• findAll(): Retorna uma lista de todas as entidades Uf.
• deleteById(Integer id): Deleta uma Uf pelo seu ID.
• count(): Retorna o número total de entidades Uf.
• E muitos outros, incluindo métodos para paginação e ordenação.
Métodos Personalizados Definidos na Interface:
Além dos métodos herdados, UfRepository define dois métodos de consulta
personalizados. O Spring Data JPA tem um mecanismo poderoso para criar consultas
automaticamente a partir da assinatura dos métodos (query methods).
• public Uf findByCoduf(Integer id);
– Este método busca uma entidade Uf com base no valor do seu atributo
coduf.
– O Spring Data JPA interpreta o nome do método: “find By Coduf”. Ele
procura um atributo chamado coduf na entidade Uf e cria uma consulta
para encontrar um registro onde coduf seja igual ao parâmetro id
fornecido.
– Retorna um único objeto Uf ou null se nenhuma UF for encontrada com
o código especificado.
• public Uf findByNomeuf(String nomeuf);
– Este método busca uma entidade Uf com base no valor do seu atributo
nomeuf.
– Similarmente, o Spring Data JPA interpreta o nome do método: “find By
Nomeuf”. Ele procura um atributo chamado nomeuf na entidade Uf e cria
uma consulta para encontrar um registro onde nomeuf seja igual ao
parâmetro nomeuf fornecido (ignorando maiúsculas/minúsculas
dependendo da configuração do banco de dados e da estratégia de
consulta).
– Retorna um único objeto Uf ou null se nenhuma UF for encontrada com
o nome especificado.
Uso no Sistema:
A interface UfRepository será injetada (usando @Autowired) em classes de
serviço (como UfService) para permitir que a lógica de negócios realize operações de
persistência relacionadas às Unidades Federativas. O Spring Data JPA cuidará da
implementação concreta desta interface em tempo de execução, eliminando a
necessidade de escrever implementações DAO (Data Access Object) manualmente.
2.2. Repositório SexoRepository.java
A interface SexoRepository é a camada de acesso a dados para a entidade
Sexo. Similarmente ao UfRepository, ela estende JpaRepository do Spring Data JPA,
o que lhe confere automaticamente métodos para operações CRUD e outras
funcionalidades de persistência para a entidade Sexo.
package com.fatec.comercio.repository;

// Imports omitidos para brevidade (incluiriam JpaRepository, List,


Query, etc.)
import com.fatec.comercio.models.Sexo;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List; // Exemplo de import que poderia estar presente

public interface SexoRepository extends JpaRepository<Sexo, Integer> {

public Sexo findByCodsexo(Integer id);


public Sexo findByNomesexo(String nomesexo);

Declaração da Interface:
• public interface SexoRepository extends JpaRepository<Sexo,
Integer>:
– Declara uma interface pública SexoRepository.
– Ao estender JpaRepository<Sexo, Integer>, esta interface herda
métodos CRUD para a entidade Sexo, cuja chave primária (codsexo) é
do tipo Integer.
Métodos Herdados (Exemplos Comuns de JpaRepository):
Assim como UfRepository, SexoRepository herda métodos como save(),
findById(), findAll(), deleteById(), count(), entre outros, aplicáveis à entidade
Sexo.

Métodos Personalizados Definidos na Interface:


SexoRepository define dois métodos de consulta personalizados, que o Spring
Data JPA implementará automaticamente com base em seus nomes:
• public Sexo findByCodsexo(Integer id);
– Este método busca uma entidade Sexo pelo valor do seu atributo
codsexo.
– O Spring Data JPA interpreta “find By Codsexo” e gera a consulta
correspondente para encontrar um registro onde o campo codsexo seja
igual ao parâmetro id.
– Retorna um objeto Sexo ou null se não for encontrado.
• public Sexo findByNomesexo(String nomesexo);
– Este método busca uma entidade Sexo pelo valor do seu atributo
nomesexo.
– O Spring Data JPA interpreta “find By Nomesexo” e gera a consulta para
encontrar um registro onde o campo nomesexo corresponda ao
parâmetro nomesexo.
– Retorna um objeto Sexo ou null se não for encontrado.
Código Comentado (Exemplos Adicionais e Observações):
O arquivo SexoRepository.java contém uma seção de código comentado que
ilustra outras capacidades do Spring Data JPA, como:
• Query methods com múltiplos critérios: findByCodsexoAndNomesexo,
findByCodsexoOrNomesexo.
• Query methods com operadores de comparação: findByCodsexoBetween,
findByCodsexoLessThan, findByCodsexoGreaterThanEqual.
• Query methods com operadores de string: findByNomesexoLike (para
padrões), findByNomesexoContaining (para substrings),
findByNomesexoStartWith (para prefixos).
• Query methods com operador In: findByCodsexoIn (para buscar por uma
coleção de IDs).
• Ordenação: findByNomesexoOrderByAsc e findByNomesexoOrderByDesc.
(Nota: A sintaxe correta para ordenação por um campo específico seria, por
exemplo, findByAlgumCampoOrderByNomesexoAsc ou
findAllByOrderByNomesexoAsc).
• Paginação: Um exemplo comentado de como seria um método para paginação:
Page<Sexo> findByNomesexo(String nomesexo, Pageable pageable); .
• Consultas JPQL com @Query: @Query("select s from sexo s where
s.codsexo > 2") List<Sexo> retornaTodosMaioresQue2();
– Esta é uma forma de definir consultas personalizadas usando Java
Persistence Query Language (JPQL).
– Observação: No JPQL, deve-se referenciar o nome da Entidade (Sexo) e
não o nome da tabela (sexo, a menos que explicitamente mapeado
assim). Portanto, a consulta correta seria select s from Sexo s where
s.codsexo > 2.

Uso no Sistema:
A interface SexoRepository será injetada em classes de serviço (como
SexoService) para fornecer acesso aos dados da entidade Sexo, permitindo que a
lógica de negócios execute operações de persistência relacionadas a sexo. O Spring
Data JPA gerencia a implementação desta interface em tempo de execução.

2.3. Repositório CidadeRepository.java


A interface CidadeRepository é a camada de acesso a dados designada para a
entidade Cidade. Seguindo o padrão dos repositórios anteriores, ela estende
JpaRepository do Spring Data JPA, o que lhe concede automaticamente um conjunto
robusto de métodos para operações de persistência (CRUD) e consultas relacionadas à
entidade Cidade.
package com.fatec.comercio.repository;

// Imports omitidos para brevidade (incluiriam JpaRepository, List, etc.)


import com.fatec.comercio.models.Cidade;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CidadeRepository extends JpaRepository<Cidade, Integer>


{

public Cidade findByCodcidade(Integer id);


public Cidade findByNomecidade(String nomecidade);
}

Declaração da Interface:
• public interface CidadeRepository extends JpaRepository<Cidade,
Integer>:
– Declara uma interface pública denominada CidadeRepository.
– Ao estender JpaRepository<Cidade, Integer>, esta interface herda
um conjunto completo de métodos CRUD para a entidade Cidade. O tipo
da chave primária da entidade Cidade (codcidade) é Integer.
Métodos Herdados (Exemplos Comuns de JpaRepository):
Assim como os outros repositórios, CidadeRepository herda métodos padrão
como save(Cidade entity), findById(Integer id), findAll(),
deleteById(Integer id), count(), e outros, todos aplicáveis à entidade Cidade.

Métodos Personalizados Definidos na Interface:


CidadeRepository define dois métodos de consulta personalizados, que o
Spring Data JPA implementará automaticamente com base em seus nomes:
• public Cidade findByCodcidade(Integer id);
– Este método é projetado para buscar uma entidade Cidade específica
com base no valor do seu atributo codcidade.
– O Spring Data JPA interpreta o nome do método (“find By Codcidade”) e
gera a consulta SQL ou JPQL apropriada para encontrar um registro
onde o campo codcidade corresponda ao parâmetro id fornecido.
– Espera-se que retorne um único objeto Cidade ou null se nenhuma
cidade com o código especificado for encontrada.
• public Cidade findByNomecidade(String nomecidade);
– Este método busca uma entidade Cidade com base no valor do seu
atributo nomecidade.
– O Spring Data JPA, ao analisar o nome do método (“find By
Nomecidade”), cria uma consulta para localizar um registro onde o
campo nomecidade seja igual ao parâmetro nomecidade fornecido. A
sensibilidade a maiúsculas e minúsculas pode depender da configuração
do banco de dados.
– Retorna um único objeto Cidade ou null caso nenhuma cidade com o
nome especificado seja encontrada.
Uso no Sistema:
A interface CidadeRepository será tipicamente injetada (utilizando a anotação
@Autowired) em classes de serviço, como CidadeService. Isso permite que a camada
de serviço execute operações de persistência relacionadas às cidades, como buscar,
salvar, atualizar ou deletar registros de cidades, sem a necessidade de escrever
implementações DAO manuais. O Spring Data JPA se encarrega de fornecer a
implementação concreta para esta interface em tempo de execução, simplificando
significativamente o desenvolvimento da camada de acesso a dados.

2.4. Repositório CepRepository.java


A interface CepRepository serve como a camada de acesso a dados para a
entidade Cep. Assim como os outros repositórios do projeto, ela estende
JpaRepository do Spring Data JPA, o que lhe fornece, por herança, um conjunto de
métodos para operações CRUD (Create, Read, Update, Delete) e outras
funcionalidades de persistência para a entidade Cep.
package com.fatec.comercio.repository;

// Imports omitidos para brevidade (incluiriam JpaRepository, List, etc.)


import com.fatec.comercio.models.Cep;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CepRepository extends JpaRepository<Cep, Integer> {

public Cep findByCodcep(Integer id);


public Cep findByNumerocep(String numerocep);

/* Código comentado com exemplos de outros query methods e uma @Query


personalizada (similar ao SexoRepository)
public Sexo findByCodsexoAndNomesexo(Integer codsexo, String
nomesexo); // Exemplo incorreto aqui, deveria ser relacionado a Cep
// ... outros exemplos comentados ...
@Query("select s from sexo s where s.codsexo > 2") // Exemplo
incorreto aqui, deveria ser relacionado a Cep
List<Sexo> retornaTodosMaioresQue2(); // Exemplo incorreto aqui,
deveria ser relacionado a Cep
*/
}

Declaração da Interface:
• public interface CepRepository extends JpaRepository<Cep, Integer> :
– Declara uma interface pública chamada CepRepository.
– Ao estender JpaRepository<Cep, Integer>, esta interface herda
métodos CRUD para a entidade Cep. A chave primária da entidade Cep
(codcep) é do tipo Integer.
Métodos Herdados (Exemplos Comuns de JpaRepository):
CepRepository herda automaticamente métodos padrão como save(Cep
entity), findById(Integer id), findAll(), deleteById(Integer id), count(),
entre outros, todos aplicáveis à entidade Cep.
Métodos Personalizados Definidos na Interface:
CepRepository define dois métodos de consulta personalizados, que o Spring
Data JPA implementará com base em seus nomes:
• public Cep findByCodcep(Integer id);
– Este método é destinado a buscar uma entidade Cep específica com base
no valor do seu atributo codcep.
– O Spring Data JPA interpreta o nome do método (“find By Codcep”) e
gera a consulta correspondente para encontrar um registro onde o
campo codcep seja igual ao parâmetro id fornecido.
– Espera-se que retorne um único objeto Cep ou null se nenhum CEP com
o código especificado for encontrado.
• public Cep findByNumerocep(String numerocep);
– Este método busca uma entidade Cep com base no valor do seu atributo
numerocep.
– O Spring Data JPA, ao analisar o nome do método (“find By
Numerocep”), cria uma consulta para localizar um registro onde o
campo numerocep seja igual ao parâmetro numerocep fornecido.
– Retorna um único objeto Cep ou null caso nenhum CEP com o número
especificado seja encontrado.
Código Comentado (Observações):
O arquivo CepRepository.java também contém uma seção de código
comentado. É importante notar que os exemplos dentro deste bloco comentado
(findByCodsexoAndNomesexo, a query @Query("select s from sexo s where
s.codsexo > 2"), etc.) parecem ter sido copiados de SexoRepository e não foram
adaptados para a entidade Cep. Em um contexto real, esses exemplos deveriam
referenciar atributos e a entidade Cep se fossem destinados a ela.
Uso no Sistema:
A interface CepRepository será injetada (usando @Autowired) em classes de
serviço que necessitam interagir com dados de CEPs. Isso permite que a lógica de
negócios realize operações de persistência relacionadas aos CEPs, como buscar,
salvar, ou deletar registros de CEPs, com o Spring Data JPA gerenciando a
implementação da interface em tempo de execução. Isso abstrai a complexidade do
acesso direto ao banco de dados.

2.5. Repositório BairroRepository.java


A interface BairroRepository é a camada de acesso a dados para a entidade
Bairro. Seguindo o padrão estabelecido nos repositórios anteriores, ela estende
JpaRepository do Spring Data JPA. Esta herança fornece automaticamente um
conjunto de métodos para operações CRUD (Create, Read, Update, Delete) e outras
funcionalidades de persistência para a entidade Bairro.
package com.fatec.comercio.repository;

// Imports omitidos para brevidade (incluiriam JpaRepository, List, etc.)


import com.fatec.comercio.models.Bairro;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BairroRepository extends JpaRepository<Bairro, Integer>


{
public Bairro findByCodbairro(Integer id);
public Bairro findByNomebairro(String nomebairro);

/* Código comentado com exemplos de outros query methods e uma @Query


personalizada (similar ao SexoRepository e CepRepository)
// ... exemplos comentados ...
*/
}

Declaração da Interface:
• public interface BairroRepository extends JpaRepository<Bairro,
Integer>:
– Declara uma interface pública chamada BairroRepository.
– Ao estender JpaRepository<Bairro, Integer>, esta interface herda
métodos CRUD para a entidade Bairro. A chave primária da entidade
Bairro (codbairro) é do tipo Integer.

Métodos Herdados (Exemplos Comuns de JpaRepository):


BairroRepository herda automaticamente métodos padrão como
save(Bairro entity), findById(Integer id), findAll(), deleteById(Integer id),
count(), entre outros, todos aplicáveis à entidade Bairro.

Métodos Personalizados Definidos na Interface:


BairroRepository define dois métodos de consulta personalizados, que o
Spring Data JPA implementará com base em seus nomes:
• public Bairro findByCodbairro(Integer id);
– Este método é destinado a buscar uma entidade Bairro específica com
base no valor do seu atributo codbairro.
– O Spring Data JPA interpreta o nome do método (“find By Codbairro”) e
gera a consulta correspondente para encontrar um registro onde o
campo codbairro seja igual ao parâmetro id fornecido.
– Espera-se que retorne um único objeto Bairro ou null se nenhum
bairro com o código especificado for encontrado.
• public Bairro findByNomebairro(String nomebairro);
– Este método busca uma entidade Bairro com base no valor do seu
atributo nomebairro.
– O Spring Data JPA, ao analisar o nome do método (“find By
Nomebairro”), cria uma consulta para localizar um registro onde o
campo nomebairro seja igual ao parâmetro nomebairro fornecido.
– Retorna um único objeto Bairro ou null caso nenhum bairro com o
nome especificado seja encontrado.
Código Comentado (Observações):
Assim como em CepRepository.java, o arquivo BairroRepository.java
contém uma seção de código comentado com exemplos que parecem ter sido copiados
de SexoRepository.java e não foram adaptados para a entidade Bairro. Estes
exemplos, se fossem para Bairro, deveriam referenciar atributos e a entidade Bairro.
Uso no Sistema:
A interface BairroRepository será injetada (usando @Autowired) em classes
de serviço, como BairroService, que necessitam interagir com dados de bairros. Isso
permite que a lógica de negócios realize operações de persistência relacionadas aos
bairros, como buscar, salvar, ou deletar registros de bairros. O Spring Data JPA
gerencia a implementação da interface em tempo de execução, simplificando o
desenvolvimento da camada de acesso a dados.

3.1. Serviço UfService.java


A classe UfService encapsula a lógica de negócios relacionada à entidade Uf.
Ela atua como uma camada intermediária entre os controladores (que lidam com as
requisições HTTP) e os repositórios (que interagem com o banco de dados). Esta
classe é anotada com @Service, indicando ao Spring que ela é um componente de
serviço e deve ser gerenciada pelo contêiner de Injeção de Dependência (DI).
package com.fatec.comercio.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fatec.comercio.models.Uf;
import com.fatec.comercio.repository.UfRepository;

@Service
public class UfService {

//injeção de dependência
@Autowired
private UfRepository ufRepository;

//Criei o Construtor - Aqui o Erro


UfService (UfRepository ufRepository){
this.ufRepository = ufRepository;
}

public List<Uf> allUfs(){


return ufRepository.findAll();
}

public Uf ufId(Integer id){


return ufRepository.findByCoduf(id);
}
public Uf ufNomeuf(String nomeuf){
return ufRepository.findByNomeuf(nomeuf);
}

public void apagaId(Integer id){


ufRepository.deleteById(id);
}

public Uf salvarUf(Uf uf){


return ufRepository.save(uf);
}

public void editaUf(Uf uf, Integer id){


uf.setCoduf(id); // Garante que o ID da UF a ser editada é o
correto
ufRepository.save(uf); // O método save também atualiza se a
entidade já existe (baseado no ID)
}
}

Anotações e Injeção de Dependência:


• @Service: Marca a classe como um serviço Spring, tornando-a elegível para
component scanning e DI.
• @Autowired private UfRepository ufRepository;: Esta anotação realiza a
injeção de dependência. O Spring automaticamente cria e injeta uma instância
de UfRepository (ou uma implementação gerenciada pelo Spring Data JPA)
neste atributo. Isso permite que UfService utilize os métodos de
UfRepository para acessar os dados das UFs.

Construtor:
• UfService (UfRepository ufRepository){ this.ufRepository =
ufRepository; }: Este é um construtor que recebe uma instância de
UfRepository. Embora a injeção de dependência via @Autowired no campo já
seja suficiente, a injeção via construtor é frequentemente considerada uma
melhor prática, pois torna as dependências explícitas e facilita os testes
unitários. O comentário “Aqui o Erro” sugere que talvez houvesse alguma
intenção ou problema anterior com este construtor, mas na forma apresentada,
ele é uma forma válida de injeção de dependência (embora redundante se
@Autowired no campo já estiver presente e funcionando como esperado pelo
desenvolvedor).
Métodos do Serviço:
Os métodos em UfService geralmente delegam as chamadas para os métodos
correspondentes em UfRepository e podem adicionar lógica de negócios adicional se
necessário (embora, nestes exemplos, eles sejam principalmente pass-throughs
diretos).
• public List<Uf> allUfs(): Retorna uma lista de todas as UFs cadastradas.
Ele chama o método findAll() do ufRepository.

• public Uf ufId(Integer id): Busca e retorna uma UF específica pelo seu


código (coduf). Ele chama o método findByCoduf(id) do ufRepository.

• public Uf ufNomeuf(String nomeuf): Busca e retorna uma UF específica pelo


seu nome (nomeuf). Ele chama o método findByNomeuf(nomeuf) do
ufRepository.

• public void apagaId(Integer id): Remove uma UF do banco de dados com


base no seu ID. Ele chama o método deleteById(id) do ufRepository.

• public Uf salvarUf(Uf uf): Salva uma nova UF no banco de dados ou


atualiza uma existente se ela já possuir um ID. Ele chama o método save(uf)
do ufRepository. O método save do JpaRepository é inteligente o suficiente
para inserir um novo registro se a entidade não tiver ID, ou atualizar um
registro existente se a entidade tiver um ID que já existe no banco.

• public void editaUf(Uf uf, Integer id): Edita/atualiza os dados de uma


UF existente.

– uf.setCoduf(id);: Primeiro, ele garante que o objeto Uf que está sendo


passado tenha o coduf correto (o ID da UF a ser atualizada). Isso é
importante para que o método save do repositório saiba qual registro
atualizar.
– ufRepository.save(uf);: Em seguida, chama o método save(uf) do
repositório. Como uf agora tem um ID que (presumivelmente) já existe
no banco de dados, o JPA executará uma operação de atualização.
Propósito e Uso:
A classe UfService centraliza a lógica de manipulação de dados para UFs. Os
controladores (UfController, por exemplo) interagirão com UfService em vez de
interagir diretamente com UfRepository. Essa separação de responsabilidades
melhora a organização do código, facilita a testabilidade e permite a adição de lógica
de negócios mais complexa (como validações, transformações de dados, orquestração
de chamadas a múltiplos repositórios, etc.) na camada de serviço sem poluir os
controladores ou os repositórios.

3.2. Serviço SexoService.java


A classe SexoService é responsável por gerenciar a lógica de negócios
associada à entidade Sexo. Ela serve como uma camada de abstração entre os
controladores que manipulam dados de sexo e o SexoRepository, que lida
diretamente com a persistência desses dados. A anotação @Service indica que esta
classe é um componente de serviço gerenciado pelo Spring.
package com.fatec.comercio.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fatec.comercio.models.Sexo;
import com.fatec.comercio.repository.SexoRepository;

@Service
public class SexoService {

//injeção de dependência
@Autowired
private SexoRepository sexoRepository;

//Criei o Construtor - Aqui o Erro


SexoService (SexoRepository sexoRepository){
this.sexoRepository = sexoRepository;
}

public List<Sexo> allSexos(){


return sexoRepository.findAll();
}

public Sexo sexoId(Integer id){


return sexoRepository.findByCodsexo(id);
}

public Sexo sexoNomeSexo(String nomesexo){


return sexoRepository.findByNomesexo(nomesexo);
}

public void apagaId(Integer id){


sexoRepository.deleteById(id);
}

public Sexo salvarSexo(Sexo sexo){


return sexoRepository.save(sexo);
}

public void editaSexo(Sexo sexo, Integer id){


sexo.setCodsexo(id); // Garante que o ID do Sexo a ser editado é
o correto
sexoRepository.save(sexo); // O método save também atualiza se a
entidade já existe
}
}

Anotações e Injeção de Dependência:


• @Service: Classifica SexoService como um componente de serviço no contexto
do Spring, tornando-o elegível para injeção de dependência e outras
funcionalidades do framework.
• @Autowired private SexoRepository sexoRepository;: Esta anotação injeta
automaticamente uma instância de SexoRepository (gerenciada pelo Spring
Data JPA) no atributo sexoRepository. Isso permite que SexoService utilize os
métodos de SexoRepository para interagir com o banco de dados.
Construtor:
• SexoService (SexoRepository sexoRepository){ this.sexoRepository =
sexoRepository; }: Este construtor permite a injeção de SexoRepository via
construtor. Assim como em UfService, se a injeção de campo com @Autowired
já está configurada, este construtor pode ser redundante ou uma preferência
de estilo para tornar as dependências mais explícitas e facilitar testes. O
comentário “Aqui o Erro” novamente sugere uma possível questão histórica ou
intenção não totalmente clara no código original, mas a forma como está
apresentado é uma maneira válida de realizar a injeção.
Métodos do Serviço:
Os métodos em SexoService geralmente delegam as operações para
SexoRepository, podendo incorporar lógica de negócios adicional se necessário. Nos
exemplos fornecidos, eles atuam principalmente como uma fachada para o
repositório.
• public List<Sexo> allSexos(): Retorna uma lista de todas as entidades Sexo
cadastradas. Este método chama sexoRepository.findAll().

• public Sexo sexoId(Integer id): Busca e retorna uma entidade Sexo


específica pelo seu codsexo. Este método chama
sexoRepository.findByCodsexo(id).

• public Sexo sexoNomeSexo(String nomesexo): Busca e retorna uma


entidade Sexo específica pelo seu nomesexo. Este método chama
sexoRepository.findByNomesexo(nomesexo) .

• public void apagaId(Integer id): Remove uma entidade Sexo do banco de


dados com base no seu ID. Este método chama
sexoRepository.deleteById(id).

• public Sexo salvarSexo(Sexo sexo): Salva uma nova entidade Sexo ou


atualiza uma existente. Este método chama sexoRepository.save(sexo). O
método save do JpaRepository lida tanto com a inserção de novos registros (se
o ID for nulo ou não existir) quanto com a atualização de registros existentes
(se o ID já existir).

• public void editaSexo(Sexo sexo, Integer id): Atualiza os dados de uma


entidade Sexo existente.

– sexo.setCodsexo(id);: Garante que o objeto Sexo que está sendo


passado para atualização tenha o codsexo correto, que é o ID do registro
a ser modificado.
– sexoRepository.save(sexo);: Chama o método save do repositório.
Como o objeto sexo agora possui um ID que (presumivelmente) já
existe, o JPA executará uma operação de atualização no banco de dados.
Propósito e Uso:
A classe SexoService centraliza as operações de negócios relacionadas à
entidade Sexo. Os controladores que manipulam dados de sexo (como
SexoController) devem interagir com SexoService em vez de acessar
SexoRepository diretamente. Esta separação de responsabilidades promove um
design mais limpo, melhora a testabilidade e oferece um local apropriado para
implementar validações, transformações de dados ou qualquer outra lógica de
negócios específica para a entidade Sexo antes ou depois das operações de
persistência.

3.3. Serviço CidadeService.java


A classe CidadeService é responsável por orquestrar as operações e a lógica
de negócios relacionadas à entidade Cidade. Ela atua como um intermediário entre os
controladores que lidam com requisições HTTP para cidades e os repositórios
(CidadeRepository e UfRepository) que interagem com o banco de dados. Esta
classe é anotada com @Service, indicando ao Spring que é um componente de serviço
gerenciado pelo seu contêiner de Injeção de Dependência (DI).
package com.fatec.comercio.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fatec.comercio.forms.CidadeForm;
import com.fatec.comercio.models.Cidade;
import com.fatec.comercio.models.Uf;
import com.fatec.comercio.repository.CidadeRepository;
import com.fatec.comercio.repository.UfRepository;

@Service
public class CidadeService {

@Autowired
private CidadeRepository cidadeRepository;
@Autowired
private UfRepository ufRepository; // Dependência adicional para
buscar UFs

//Criei o Construtor - Aqui o Erro


CidadeService (CidadeRepository cidadeRepository){
this.cidadeRepository = cidadeRepository;
// Nota: ufRepository não está sendo injetado/atribuído neste
construtor
}

public List<Cidade> allCidades(){


return cidadeRepository.findAll();
}

public Cidade cidadeId(Integer id){


return cidadeRepository.findByCodcidade(id);
}

public Cidade cidadeNomecidade(String nomecidade){


return cidadeRepository.findByNomecidade(nomecidade);
}

public void apagaId(Integer id){


cidadeRepository.deleteById(id);
}

public Cidade salvarCidade(CidadeForm cidadeForm){


// Converte o CidadeForm (DTO) para uma entidade Cidade
// O método converter provavelmente busca a Uf usando
ufRepository
Cidade cidade = cidadeForm.converter(ufRepository);
return cidadeRepository.save(cidade);
}

public Cidade editaCidade(CidadeForm cidadeForm, Integer id){


// Busca a UF pelo nome fornecido no formulário
Uf uf = ufRepository.findByNomeuf(cidadeForm.getNomeuf());

// Busca a cidade existente pelo ID para atualização


// Nota: getOne() é lazy-loaded e pode causar problemas se a
sessão for fechada.
// findById(id).orElse(null) ou .orElseThrow() seria mais
robusto.
Cidade cidade = cidadeRepository.getOne(id);

cidade.setNomecidade(cidadeForm.getNomecidade());
cidade.setUf(uf); // Define a UF (potencialmente atualizada)
// O save aqui não está sendo chamado, então a edição não será
persistida.
// Deveria haver um cidadeRepository.save(cidade) para persistir
as alterações.
return cidade; // Retorna a cidade modificada (mas não persistida
no estado atual do código)
}
}

Anotações e Injeção de Dependência:


• @Service: Marca a classe como um serviço Spring.
• @Autowired private CidadeRepository cidadeRepository; : Injeta uma
instância de CidadeRepository.
• @Autowired private UfRepository ufRepository;: Injeta uma instância de
UfRepository. Esta dependência é necessária porque as operações de salvar e
editar cidades envolvem a associação com uma Uf, que pode precisar ser
buscada ou validada.
Construtor:
• CidadeService (CidadeRepository cidadeRepository){
this.cidadeRepository = cidadeRepository; }: Este construtor injeta
CidadeRepository. No entanto, ele não injeta UfRepository, que é um campo
anotado com @Autowired. Se a injeção por campo estiver funcionando,
ufRepository será injetado pelo Spring independentemente deste construtor.
Se a intenção fosse usar apenas injeção por construtor, UfRepository também
deveria ser um parâmetro do construtor. O comentário “Aqui o Erro” pode
estar relacionado a esta inconsistência ou a uma configuração anterior.
Métodos do Serviço:
• public List<Cidade> allCidades(): Retorna uma lista de todas as cidades,
delegando a chamada para cidadeRepository.findAll().

• public Cidade cidadeId(Integer id): Busca uma cidade pelo seu


codcidade, chamando cidadeRepository.findByCodcidade(id) .

• public Cidade cidadeNomecidade(String nomecidade): Busca uma cidade


pelo seu nomecidade, chamando
cidadeRepository.findByNomecidade(nomecidade).

• public void apagaId(Integer id): Deleta uma cidade pelo seu ID, chamando
cidadeRepository.deleteById(id) .

• public Cidade salvarCidade(CidadeForm cidadeForm):


– Este método é responsável por salvar uma nova cidade. Ele recebe um
CidadeForm, que é um Data Transfer Object (DTO) contendo os dados da
cidade a ser criada.
– Cidade cidade = cidadeForm.converter(ufRepository); : O
CidadeForm possui um método converter que, presumivelmente,
transforma o DTO em uma entidade Cidade. Este método converter
utiliza o ufRepository para buscar e associar a Uf correta à nova cidade
com base no nome da UF fornecido no formulário.
– return cidadeRepository.save(cidade);: Após a conversão, a nova
entidade Cidade é salva no banco de dados usando
cidadeRepository.save(cidade).
• public Cidade editaCidade(CidadeForm cidadeForm, Integer id) :

– Este método visa atualizar uma cidade existente.


– Uf uf = ufRepository.findByNomeuf(cidadeForm.getNomeuf()); :
Busca a entidade Uf com base no nome da UF fornecido no CidadeForm.
Isso permite atualizar a UF associada à cidade, se necessário.
– Cidade cidade = cidadeRepository.getOne(id);: Busca a entidade
Cidade existente pelo seu ID. Observação importante: getOne() do
JpaRepository retorna uma referência proxy (lazy-loaded) para a
entidade. Se os dados da entidade não forem acessados dentro de uma
transação ativa, isso pode levar a uma LazyInitializationException.
É geralmente mais seguro usar findById(id).orElseThrow(() -> new
EntityNotFoundException("Cidade não encontrada")) ou similar
para carregar a entidade completamente.
– cidade.setNomecidade(cidadeForm.getNomecidade());: Atualiza o
nome da cidade.
– cidade.setUf(uf);: Atualiza a UF associada à cidade.
– return cidade;: Ponto crítico: O método, como está escrito, retorna o
objeto cidade modificado em memória, mas não chama
cidadeRepository.save(cidade) para persistir essas alterações no
banco de dados. Para que a edição seja efetivada, uma chamada a
cidadeRepository.save(cidade) é necessária antes do return.

Propósito e Uso:
CidadeService centraliza a lógica de negócios para a entidade Cidade. Ele lida
com a conversão de DTOs (CidadeForm) para entidades, a busca de entidades
relacionadas (Uf), e a delegação de operações de persistência para os repositórios. Os
controladores (CidadeController) devem usar este serviço para todas as operações
relacionadas a cidades, promovendo uma arquitetura em camadas bem definida.

3.4. Serviço BairroService.java


A classe BairroService é responsável por encapsular a lógica de negócios
relacionada à entidade Bairro. Ela serve como uma camada intermediária entre os
controladores que manipulam dados de bairros e o BairroRepository, que lida com a
persistência desses dados. A anotação @Service indica que esta classe é um
componente de serviço gerenciado pelo Spring.
package com.fatec.comercio.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fatec.comercio.models.Bairro;
import com.fatec.comercio.repository.BairroRepository;

@Service
public class BairroService {

@Autowired
private BairroRepository bairroRepository;

//Criei o Construtor - Aqui o Erro


BairroService (BairroRepository bairroRepository){
this.bairroRepository = bairroRepository;
}

public List<Bairro> allBairros(){


return bairroRepository.findAll();
}

public Bairro bairroId(Integer id){


return bairroRepository.findByCodbairro(id);
}

public Bairro bairroNomeBairro(String nomebairro){


return bairroRepository.findByNomebairro(nomebairro);
}

public void apagaId(Integer id){


bairroRepository.deleteById(id);
}

public Bairro salvarBairro(Bairro bairro){


return bairroRepository.save(bairro);
}

public void editaBairro(Bairro bairro, Integer id){


bairro.setCodbairro(id); // Garante que o ID do Bairro a ser
editado é o correto
bairroRepository.save(bairro); // O método save também atualiza
se a entidade já existe
}
}

Anotações e Injeção de Dependência:


• @Service: Classifica BairroService como um componente de serviço no
contexto do Spring, tornando-o elegível para injeção de dependência e outras
funcionalidades do framework.
• @Autowired private BairroRepository bairroRepository; : Esta anotação
injeta automaticamente uma instância de BairroRepository (gerenciada pelo
Spring Data JPA) no atributo bairroRepository. Isso permite que
BairroService utilize os métodos de BairroRepository para interagir com o
banco de dados.
Construtor:
• BairroService (BairroRepository bairroRepository){
this.bairroRepository = bairroRepository; }: Este construtor permite a
injeção de BairroRepository via construtor. Assim como nos serviços
anteriores, se a injeção de campo com @Autowired já está configurada, este
construtor pode ser redundante ou uma preferência de estilo para tornar as
dependências mais explícitas e facilitar testes. O comentário “Aqui o Erro”
novamente sugere uma possível questão histórica ou intenção não totalmente
clara no código original, mas a forma como está apresentado é uma maneira
válida de realizar a injeção.
Métodos do Serviço:
Os métodos em BairroService geralmente delegam as operações para
BairroRepository, podendo incorporar lógica de negócios adicional se necessário.
Nos exemplos fornecidos, eles atuam principalmente como uma fachada para o
repositório.
• public List<Bairro> allBairros(): Retorna uma lista de todas as entidades
Bairro cadastradas. Este método chama bairroRepository.findAll().

• public Bairro bairroId(Integer id): Busca e retorna uma entidade Bairro


específica pelo seu codbairro. Este método chama
bairroRepository.findByCodbairro(id).

• public Bairro bairroNomeBairro(String nomebairro): Busca e retorna


uma entidade Bairro específica pelo seu nomebairro. Este método chama
bairroRepository.findByNomebairro(nomebairro).

• public void apagaId(Integer id): Remove uma entidade Bairro do banco


de dados com base no seu ID. Este método chama
bairroRepository.deleteById(id) .
• public Bairro salvarBairro(Bairro bairro): Salva uma nova entidade
Bairro ou atualiza uma existente. Este método chama
bairroRepository.save(bairro). O método save do JpaRepository lida tanto
com a inserção de novos registros (se o ID for nulo ou não existir) quanto com
a atualização de registros existentes (se o ID já existir).

• public void editaBairro(Bairro bairro, Integer id) : Atualiza os dados


de uma entidade Bairro existente.

– bairro.setCodbairro(id);: Garante que o objeto Bairro que está


sendo passado para atualização tenha o codbairro correto, que é o ID
do registro a ser modificado.
– bairroRepository.save(bairro);: Chama o método save do
repositório. Como o objeto bairro agora possui um ID que
(presumivelmente) já existe, o JPA executará uma operação de
atualização no banco de dados.
Propósito e Uso:
A classe BairroService centraliza as operações de negócios relacionadas à
entidade Bairro. Os controladores que manipulam dados de bairros (como
BairroController) devem interagir com BairroService em vez de acessar
BairroRepository diretamente. Esta separação de responsabilidades promove um
design mais limpo, melhora a testabilidade e oferece um local apropriado para
implementar validações, transformações de dados ou qualquer outra lógica de
negócios específica para a entidade Bairro antes ou depois das operações de
persistência.

4. Formulários (DTOs - Data Transfer Objects)


Os formulários, ou Data Transfer Objects (DTOs), são classes simples usadas
para encapsular dados que são transferidos entre camadas da aplicação,
especialmente entre o cliente (requisição HTTP) e os controladores, ou entre os
controladores e os serviços. Eles ajudam a desacoplar as entidades de persistência da
interface da API e podem ser usados para validação de entrada.

4.1. Formulário CidadeForm.java


A classe CidadeForm é um DTO projetado para carregar os dados necessários
para criar ou atualizar uma entidade Cidade. Ela não é uma entidade JPA, mas sim um
objeto simples que agrupa os campos relevantes que seriam enviados em uma
requisição, como o nome da cidade e o nome da UF à qual ela pertence.
package com.fatec.comercio.forms;

import com.fatec.comercio.models.Cidade;
import com.fatec.comercio.models.Uf;
import com.fatec.comercio.repository.UfRepository;
public class CidadeForm {

private Integer codcidade; // Usado potencialmente para identificar a


cidade em atualizações, embora não seja comum em DTOs de criação
private String nomecidade;
private String nomeuf; // Nome da UF para buscar a entidade Uf
associada

// Getters e Setters
public Integer getCodcidade() {
return codcidade;
}
public void setCodcidade(Integer codcidade) {
this.codcidade = codcidade;
}
public String getNomecidade() {
return nomecidade;
}
public void setNomecidade(String nomecidade) {
this.nomecidade = nomecidade;
}
public String getNomeuf() {
return nomeuf;
}
public void setNomeuf(String nomeuf) {
this.nomeuf = nomeuf;
}

// Método de conversão para a entidade Cidade


public Cidade converter(UfRepository ufRepository) {
// TODO Auto-generated method stub // Comentário de TODO, indica
trabalho pendente ou a ser revisado
Uf uf = ufRepository.findByNomeuf(nomeuf); // Busca a entidade Uf
pelo nome
return new Cidade(nomecidade, uf); // Cria uma nova instância de
Cidade
}
}

Atributos:
• private Integer codcidade: Este campo pode ser usado para identificar uma
cidade existente durante uma operação de atualização. Para a criação de uma
nova cidade, ele geralmente seria nulo ou não utilizado, pois o código da cidade
é gerado automaticamente pelo banco de dados.
• private String nomecidade: Armazena o nome da cidade que está sendo
criada ou atualizada.
• private String nomeuf: Armazena o nome da Unidade Federativa (UF) à qual
a cidade pertence. Este nome será usado para buscar a entidade Uf
correspondente no banco de dados.
Métodos:
• Getters e Setters: A classe fornece métodos get e set padrão para todos os
seus atributos (codcidade, nomecidade, nomeuf). Estes são usados pelo
framework Spring MVC (ou similar, como Jackson para desserialização JSON)
para popular o objeto CidadeForm com os dados da requisição HTTP e para
acessar seus valores.

• public Cidade converter(UfRepository ufRepository):

– Este é um método crucial que transforma o CidadeForm (DTO) em uma


entidade Cidade pronta para ser persistida.
– Ele recebe uma instância de UfRepository como parâmetro. Isso é
necessário para buscar a entidade Uf completa com base no nomeuf
fornecido no formulário.
– Uf uf = ufRepository.findByNomeuf(nomeuf);: Utiliza o
ufRepository para encontrar a entidade Uf que corresponde ao nomeuf.
– return new Cidade(nomecidade, uf);: Cria e retorna uma nova
instância da entidade Cidade, utilizando o construtor de Cidade que
aceita o nome da cidade e o objeto Uf.
– O comentário // TODO Auto-generated method stub sugere que este
método pode ter sido gerado inicialmente por uma IDE e pode precisar
de revisão ou implementação adicional, embora sua funcionalidade
principal (buscar a UF e criar a Cidade) esteja presente.
Propósito e Uso:
O CidadeForm é usado principalmente na camada de Controller (por exemplo,
em CidadeController) para receber dados de requisições HTTP (geralmente no
corpo de uma requisição POST ou PUT, em formato JSON).
1. Quando uma requisição para criar ou atualizar uma cidade chega ao controller,
os dados da requisição são mapeados para uma instância de CidadeForm.
2. O controller então passa este CidadeForm para a camada de serviço (por
exemplo, CidadeService).
3. O serviço utiliza o método converter() do CidadeForm para obter uma
entidade Cidade.
4. Esta entidade Cidade é então persistida ou atualizada no banco de dados
através do CidadeRepository.
Usar DTOs como CidadeForm é uma boa prática porque:
• Desacoplamento: Separa a representação dos dados da API (DTO) da
representação dos dados no banco de dados (Entidade).
• Validação: DTOs são um bom lugar para adicionar anotações de validação
(usando Bean Validation, por exemplo, com anotações como @NotNull, @Size,
etc.) para garantir que os dados recebidos sejam válidos antes de tentar
processá-los.
• Flexibilidade: Permite que a estrutura dos dados enviados pela API evolua
independentemente da estrutura da entidade no banco de dados.
• Segurança: Evita a exposição direta de todos os campos da entidade na API,
permitindo controlar quais dados são recebidos e processados.

5. Controladores (Controllers)
Os controladores são responsáveis por lidar com as requisições HTTP de
entrada, processá-las (geralmente delegando para a camada de serviço) e retornar
uma resposta HTTP ao cliente. Eles são a porta de entrada da API.

5.1. Controlador UfController.java


A classe UfController é um controlador REST (@RestController) que
gerencia as requisições HTTP relacionadas à entidade Uf (Unidade Federativa). Ela
define endpoints para criar, ler, atualizar e deletar (CRUD) UFs.
package com.fatec.comercio.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fatec.comercio.models.Uf;
import com.fatec.comercio.service.UfService;
import jakarta.transaction.Transactional;
import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// import org.springframework.web.bind.annotation.RequestParam; // Não
utilizado neste controller
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PutMapping;

@RestController
@RequestMapping("/ufs") // Mapeia todas as requisições para /ufs para
este controller
public class UfController {

private final UfService ufService; // Injeção de dependência do


serviço UfService

//Criei o Construtor - Esquecemos Essa Parada


UfController(UfService ufService) {
this.ufService = ufService;
}

// Endpoint para listar todas as UFs


@GetMapping("")
public List<Uf> getUf() {
return ufService.allUfs();
}

// Endpoint para buscar uma UF pelo ID


@GetMapping("/{id}")
public Uf pegaUfId(@PathVariable Integer id) {
return ufService.ufId(id);
}

// Endpoint para deletar uma UF pelo ID


@DeleteMapping("/{id}")
public String apagaSexoId(@PathVariable Integer id){ // Nome do
método um pouco confuso (apagaSexoId para Uf)
ufService.apagaId(id);
return("Uf Deletado com Sucesso = " + id);
}

// Endpoint para criar uma nova UF


@PostMapping("")
public String salvaDadosUf(@RequestBody Uf uf) {
ufService.salvarUf(uf);
return "Uf: " + uf.getNomeuf() + " Cadastrado com Sucesso.";
}

// Endpoint para atualizar uma UF existente


@PutMapping("/{id}")
@Transactional // Garante que a operação de edição ocorra dentro de
uma transação
public String atualizaDadosUf(@PathVariable Integer id, @RequestBody
Uf uf) {
ufService.editaUf(uf, id);
return "Dados atualizados com sucesso!";
}
}

Anotações e Configurações:
• @RestController: Esta é uma anotação de conveniência que combina
@Controller e @ResponseBody. Ela indica que esta classe lida com requisições
REST e que os valores retornados pelos seus métodos devem ser diretamente
ligados ao corpo da resposta HTTP (geralmente convertidos para JSON ou
XML).
• @RequestMapping("/ufs"): Mapeia todas as requisições HTTP que começam
com o caminho /ufs para os métodos manipuladores (handler methods)
dentro desta classe. Por exemplo, uma requisição GET para /ufs será tratada
pelo método getUf().
Injeção de Dependência e Construtor:
• private final UfService ufService;: Declara uma dependência final do
UfService. O uso de final junto com a injeção via construtor é uma boa
prática para garantir que a dependência seja imutável após a criação do objeto.
• UfController(UfService ufService) { this.ufService = ufService; } :
Este é o construtor da classe, que recebe uma instância de UfService. O Spring
utiliza este construtor para realizar a injeção de dependência. O comentário
“Criei o Construtor - Esquecemos Essa Parada” sugere que a injeção via
construtor foi uma adição ou correção posterior, o que é uma prática
recomendada em relação à injeção por campo (@Autowired diretamente no
campo).
Métodos (Endpoints da API):
• @GetMapping("") public List<Uf> getUf():
– Mapeia requisições HTTP GET para /ufs.
– Chama ufService.allUfs() para obter a lista de todas as UFs.
– Retorna a lista de UFs, que será convertida para JSON na resposta HTTP.
• @GetMapping("/{id}") public Uf pegaUfId(@PathVariable Integer id) :
– Mapeia requisições HTTP GET para /ufs/{id}, onde {id} é uma
variável de caminho (path variable) que representa o código da UF.
– @PathVariable Integer id: Extrai o valor de id da URL e o converte
para Integer.
– Chama ufService.ufId(id) para buscar a UF correspondente.
– Retorna a entidade Uf encontrada (ou null/erro se não encontrada,
dependendo da implementação do serviço), que será convertida para
JSON.
• @DeleteMapping("/{id}") public String apagaSexoId(@PathVariable
Integer id):
– Mapeia requisições HTTP DELETE para /ufs/{id}.
– Observação: O nome do método apagaSexoId é um pouco enganoso,
pois ele está deletando uma Uf, não um Sexo. Seria mais claro se fosse
nomeado como apagaUfId ou similar.
– Chama ufService.apagaId(id) para deletar a UF.
– Retorna uma mensagem de string indicando o sucesso da operação.
• @PostMapping("") public String salvaDadosUf(@RequestBody Uf uf) :
– Mapeia requisições HTTP POST para /ufs.
– @RequestBody Uf uf: Indica que o corpo da requisição HTTP (esperado
em formato JSON) deve ser desserializado em um objeto Uf.
– Chama ufService.salvarUf(uf) para persistir a nova UF.
– Retorna uma mensagem de string confirmando o cadastro.
• @PutMapping("/{id}") @Transactional public String
atualizaDadosUf(@PathVariable Integer id, @RequestBody Uf uf) :
– Mapeia requisições HTTP PUT para /ufs/{id}.
– @PathVariable Integer id: Extrai o ID da UF a ser atualizada da URL.
– @RequestBody Uf uf: Obtém os novos dados da UF do corpo da
requisição.
– @Transactional: Esta anotação é importante, especialmente para
operações de atualização. Ela garante que o método seja executado
dentro de uma transação do banco de dados. Se o método editaUf no
serviço modificar uma entidade gerenciada pelo JPA dentro desta
transação, as alterações podem ser automaticamente persistidas ao final
da transação (dirty checking), dependendo da configuração. No entanto,
como UfService.editaUf explicitamente chama save, a transação aqui
garante atomicidade.
– Chama ufService.editaUf(uf, id) para atualizar a UF.
– Retorna uma mensagem de string indicando o sucesso da atualização.
Propósito e Uso:
UfController expõe as funcionalidades de gerenciamento de UFs através de
uma API RESTful. Clientes HTTP (como frontends de aplicações web, aplicações
móveis ou outros serviços) podem interagir com estes endpoints para realizar
operações CRUD sobre os dados das Unidades Federativas. O controlador delega a
lógica de negócios real para UfService, mantendo-se focado em lidar com a
comunicação HTTP.

5.2. Controlador SexoController.java


A classe SexoController é um controlador REST (@RestController)
responsável por gerenciar as requisições HTTP relacionadas à entidade Sexo. Ela
define os endpoints para as operações CRUD (Criar, Ler, Atualizar, Deletar) sobre os
dados de sexo.
package com.fatec.comercio.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fatec.comercio.models.Sexo;
import com.fatec.comercio.service.SexoService;
import jakarta.transaction.Transactional;
import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// import org.springframework.web.bind.annotation.RequestParam; // Não
utilizado neste controller
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PutMapping;

@RestController
@RequestMapping("/sexos") // Mapeia todas as requisições para /sexos para
este controller
public class SexoController {

private final SexoService sexoService; // Injeção de dependência do


serviço SexoService

//Criei o Construtor - Esquecemos Essa Parada


SexoController(SexoService sexoService) {
this.sexoService = sexoService;
}

// Endpoint para listar todos os Sexos


@GetMapping("")
public List<Sexo> getSexo() {
return sexoService.allSexos();
}

// Endpoint para buscar um Sexo pelo ID


@GetMapping("/{id}")
public Sexo pegaSexoId(@PathVariable Integer id) {
return sexoService.sexoId(id);
}

// Endpoint para deletar um Sexo pelo ID


@DeleteMapping("/{id}")
public String apagaSexoId(@PathVariable Integer id){
sexoService.apagaId(id);
return("Sexo Deletado com Sucesso = " + id);
}

// Endpoint para criar um novo Sexo


@PostMapping("")
public String salvaDadosSexo(@RequestBody Sexo sexo) {
sexoService.salvarSexo(sexo);
return "Sexo: " + sexo.getNomesexo() + " Cadastrado com
Sucesso.";
}

// Endpoint para atualizar um Sexo existente


@PutMapping("/{id}")
@Transactional // Garante que a operação de edição ocorra dentro de
uma transação
public String atualizaDadosSexo(@PathVariable Integer id,
@RequestBody Sexo sexo) {
sexoService.editaSexo(sexo, id);
return "Dados atualizados com sucesso!";
}
}

Anotações e Configurações:
• @RestController: Indica que esta classe é um controlador REST, cujos
métodos retornam dados que são diretamente escritos no corpo da resposta
HTTP (geralmente em JSON).
• @RequestMapping("/sexos"): Mapeia todas as requisições HTTP que começam
com o caminho base /sexos para os métodos manipuladores definidos nesta
classe.
Injeção de Dependência e Construtor:
• private final SexoService sexoService;: Declara uma dependência final
do SexoService.
• SexoController(SexoService sexoService) { this.sexoService =
sexoService; }: Construtor utilizado pelo Spring para injetar a dependência
de SexoService. O comentário “Criei o Construtor - Esquecemos Essa Parada”
sugere que esta forma de injeção (via construtor, que é uma prática
recomendada) foi implementada posteriormente.
Métodos (Endpoints da API):
• @GetMapping("") public List<Sexo> getSexo():
– Mapeia requisições HTTP GET para /sexos.
– Chama sexoService.allSexos() para obter a lista de todas as
entidades Sexo.
– Retorna a lista de Sexo, que será serializada para JSON.
• @GetMapping("/{id}") public Sexo pegaSexoId(@PathVariable Integer
id):
– Mapeia requisições HTTP GET para /sexos/{id}, onde {id} é o código
do sexo.
– @PathVariable Integer id: Extrai o valor de id da URL.
– Chama sexoService.sexoId(id) para buscar o Sexo correspondente.
– Retorna a entidade Sexo encontrada.
• @DeleteMapping("/{id}") public String apagaSexoId(@PathVariable
Integer id):
– Mapeia requisições HTTP DELETE para /sexos/{id}.
– Chama sexoService.apagaId(id) para deletar o Sexo.
– Retorna uma mensagem de string confirmando a exclusão.
• @PostMapping("") public String salvaDadosSexo(@RequestBody Sexo
sexo):
– Mapeia requisições HTTP POST para /sexos.
– @RequestBody Sexo sexo: Indica que o corpo da requisição HTTP
(esperado em JSON) deve ser desserializado em um objeto Sexo.
– Chama sexoService.salvarSexo(sexo) para persistir a nova entidade
Sexo.
– Retorna uma mensagem de string confirmando o cadastro.
• @PutMapping("/{id}") @Transactional public String
atualizaDadosSexo(@PathVariable Integer id, @RequestBody Sexo
sexo):
– Mapeia requisições HTTP PUT para /sexos/{id}.
– @PathVariable Integer id: Extrai o ID do Sexo a ser atualizado da
URL.
– @RequestBody Sexo sexo: Obtém os novos dados do Sexo do corpo da
requisição.
– @Transactional: Garante que a operação de atualização seja executada
dentro de uma transação do banco de dados, promovendo a
atomicidade da operação.
– Chama sexoService.editaSexo(sexo, id) para atualizar a entidade
Sexo.
– Retorna uma mensagem de string indicando o sucesso da atualização.
Propósito e Uso:
SexoController serve como a interface RESTful para as operações
relacionadas à entidade Sexo. Ele recebe requisições HTTP, delega a lógica de
processamento para SexoService e retorna respostas apropriadas para o cliente. Esta
estrutura segue o padrão de arquitetura em camadas, separando as responsabilidades
de manipulação de requisições (controller) da lógica de negócios (service) e do acesso
a dados (repository).

5.3. Controlador CidadeController.java


A classe CidadeController é um controlador REST (@RestController) que
gerencia as requisições HTTP relacionadas à entidade Cidade. Ela define endpoints
para as operações CRUD (Criar, Ler, Atualizar, Deletar) sobre os dados das cidades,
utilizando CidadeService para a lógica de negócios e CidadeForm como DTO para
entrada de dados.
package com.fatec.comercio.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fatec.comercio.forms.CidadeForm; // DTO para entrada de dados
de cidade
import com.fatec.comercio.models.Cidade;
import com.fatec.comercio.service.CidadeService;
import jakarta.transaction.Transactional;
import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// import org.springframework.web.bind.annotation.RequestParam; // Não
utilizado neste controller
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PutMapping;

@RestController
@RequestMapping("/cidades") // Mapeia todas as requisições para /cidades
para este controller
public class CidadeController {

private final CidadeService cidadeService; // Injeção de dependência


do serviço CidadeService

//Criei o Construtor - Esquecemos Essa Parada


CidadeController(CidadeService cidadeService) {
this.cidadeService = cidadeService;
}

// Endpoint para listar todas as Cidades


@GetMapping("")
public List<Cidade> getCidade() {
return cidadeService.allCidades();
}

// Endpoint para buscar uma Cidade pelo ID


@GetMapping("/{id}")
public Cidade pegaCidadeId(@PathVariable Integer id) {
return cidadeService.cidadeId(id);
}

// Endpoint para deletar uma Cidade pelo ID


@DeleteMapping("/{id}")
public String apagaCidadeId(@PathVariable Integer id){
cidadeService.apagaId(id);
return("Cidade Deletada com Sucesso = " + id);
}

// Endpoint para criar uma nova Cidade


@PostMapping("")
public String salvaDadosCidade(@RequestBody CidadeForm cidadeForm) {
// Recebe CidadeForm como DTO
cidadeService.salvarCidade(cidadeForm); // Passa o DTO para o
serviço
return "Cidade: " + cidadeForm.getNomecidade() + " Cadastrada com
Sucesso.";
}

// Endpoint para atualizar uma Cidade existente


@PutMapping("/{id}")
@Transactional // Garante que a operação de edição ocorra dentro de
uma transação
public String atualizaDadosCidade(@PathVariable Integer id,
@RequestBody CidadeForm cidadeForm) { // Recebe CidadeForm
cidadeService.editaCidade(cidadeForm, id); // Passa o DTO e o ID
para o serviço
return "Dados atualizados com sucesso!";
}
}

Anotações e Configurações:
• @RestController: Designa esta classe como um controlador REST, onde os
valores de retorno dos métodos são diretamente serializados no corpo da
resposta HTTP (normalmente como JSON).
• @RequestMapping("/cidades"): Define o caminho base para todas as
requisições manipuladas por este controlador. Todas as requisições que
começam com /cidades serão direcionadas para cá.
Injeção de Dependência e Construtor:
• private final CidadeService cidadeService;: Declara uma dependência
final do CidadeService.
• CidadeController(CidadeService cidadeService) { this.cidadeService
= cidadeService; }: Construtor que o Spring utiliza para injetar a
dependência de CidadeService. O comentário “Criei o Construtor -
Esquecemos Essa Parada” indica que a injeção via construtor (uma prática
recomendada) foi uma adição ou correção posterior.
Métodos (Endpoints da API):
• @GetMapping("") public List<Cidade> getCidade():
– Mapeia requisições HTTP GET para /cidades.
– Chama cidadeService.allCidades() para obter a lista de todas as
entidades Cidade.
– Retorna a lista de Cidade, que será serializada para JSON.
• @GetMapping("/{id}") public Cidade pegaCidadeId(@PathVariable
Integer id):
– Mapeia requisições HTTP GET para /cidades/{id}, onde {id} é o
código da cidade.
– @PathVariable Integer id: Extrai o valor de id da URL.
– Chama cidadeService.cidadeId(id) para buscar a Cidade
correspondente.
– Retorna a entidade Cidade encontrada.
• @DeleteMapping("/{id}") public String apagaCidadeId(@PathVariable
Integer id):
– Mapeia requisições HTTP DELETE para /cidades/{id}.
– Chama cidadeService.apagaId(id) para deletar a Cidade.
– Retorna uma mensagem de string confirmando a exclusão.
• @PostMapping("") public String salvaDadosCidade(@RequestBody
CidadeForm cidadeForm):
– Mapeia requisições HTTP POST para /cidades.
– @RequestBody CidadeForm cidadeForm: Indica que o corpo da
requisição HTTP (esperado em JSON) deve ser desserializado em um
objeto CidadeForm (o DTO).
– Chama cidadeService.salvarCidade(cidadeForm) para processar o
DTO e persistir a nova entidade Cidade.
– Retorna uma mensagem de string confirmando o cadastro, utilizando o
nome da cidade do cidadeForm.
• @PutMapping("/{id}") @Transactional public String
atualizaDadosCidade(@PathVariable Integer id, @RequestBody
CidadeForm cidadeForm):
– Mapeia requisições HTTP PUT para /cidades/{id}.
– @PathVariable Integer id: Extrai o ID da Cidade a ser atualizada da
URL.
– @RequestBody CidadeForm cidadeForm: Obtém os novos dados da
Cidade do corpo da requisição, na forma de um CidadeForm.
– @Transactional: Garante que a operação de atualização seja executada
dentro de uma transação do banco de dados. Isso é particularmente
importante se o método de serviço editaCidade realizar múltiplas
operações no banco ou depender do dirty checking do JPA (embora, no
CidadeService analisado, a persistência da edição parecia estar
faltando uma chamada save).
– Chama cidadeService.editaCidade(cidadeForm, id) para processar
o DTO e atualizar a entidade Cidade.
– Retorna uma mensagem de string indicando o sucesso da atualização.
Propósito e Uso:
CidadeController atua como a interface RESTful para as operações
relacionadas à entidade Cidade. Ele recebe requisições HTTP, utiliza o CidadeForm
para capturar dados de entrada para criação e atualização, delega a lógica de
processamento para CidadeService e retorna respostas apropriadas para o cliente.
Esta abordagem mantém uma clara separação de responsabilidades entre as camadas
da aplicação, seguindo as melhores práticas de design de APIs REST e arquitetura
Spring Boot.
5.4. Controlador BairroController.java
A classe BairroController é um controlador REST (@RestController) que
gerencia as requisições HTTP relacionadas à entidade Bairro. Ela define os endpoints
para as operações CRUD (Criar, Ler, Atualizar, Deletar) sobre os dados dos bairros,
delegando a lógica de negócios para BairroService.
package com.fatec.comercio.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fatec.comercio.models.Bairro;
import com.fatec.comercio.service.BairroService;
import jakarta.transaction.Transactional;
import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// import org.springframework.web.bind.annotation.RequestParam; // Não
utilizado neste controller
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PutMapping;

@RestController
@RequestMapping("/bairros") // Mapeia todas as requisições para /bairros
para este controller
public class BairroController {

private final BairroService bairroService; // Injeção de dependência


do serviço BairroService

//Criei o Construtor - Esquecemos Essa Parada


BairroController(BairroService bairroService) {
this.bairroService = bairroService;
}

// Endpoint para listar todos os Bairros


@GetMapping("")
public List<Bairro> getBairros() {
return bairroService.allBairros();
}

// Endpoint para buscar um Bairro pelo ID


@GetMapping("/{id}")
public Bairro pegaBairroId(@PathVariable Integer id) {
return bairroService.bairroId(id);
}
// Endpoint para deletar um Bairro pelo ID
@DeleteMapping("/{id}")
public String apagaBairroId(@PathVariable Integer id){
bairroService.apagaId(id);
return("Bairro Deletado com Sucesso = " + id);
}

// Endpoint para criar um novo Bairro


@PostMapping("")
public String salvaDadosBairro(@RequestBody Bairro bairro) { //
Recebe a entidade Bairro diretamente
bairroService.salvarBairro(bairro);
return "Bairro: " + bairro.getNomebairro() + " Cadastrado com
Sucesso.";
}

// Endpoint para atualizar um Bairro existente


@PutMapping("/{id}")
@Transactional // Garante que a operação de edição ocorra dentro de
uma transação
public String atualizaDadosBairro(@PathVariable Integer id,
@RequestBody Bairro bairro) {
bairroService.editaBairro(bairro, id);
return "Dados atualizados com sucesso!";
}
}

Anotações e Configurações:
• @RestController: Designa esta classe como um controlador REST. Os valores
de retorno dos seus métodos são diretamente serializados no corpo da
resposta HTTP (geralmente como JSON).
• @RequestMapping("/bairros"): Define o caminho base para todas as
requisições manipuladas por este controlador. Todas as requisições que
começam com /bairros serão direcionadas para os métodos desta classe.
Injeção de Dependência e Construtor:
• private final BairroService bairroService;: Declara uma dependência
final do BairroService.
• BairroController(BairroService bairroService) { this.bairroService
= bairroService; }: Construtor utilizado pelo Spring para injetar a
dependência de BairroService. O comentário “Criei o Construtor -
Esquecemos Essa Parada” sugere que a injeção via construtor (uma prática
recomendada) foi uma adição ou correção posterior.
Métodos (Endpoints da API):
• @GetMapping("") public List<Bairro> getBairros():
– Mapeia requisições HTTP GET para /bairros.
– Chama bairroService.allBairros() para obter a lista de todas as
entidades Bairro.
– Retorna a lista de Bairro, que será serializada para JSON.
• @GetMapping("/{id}") public Bairro pegaBairroId(@PathVariable
Integer id):
– Mapeia requisições HTTP GET para /bairros/{id}, onde {id} é o
código do bairro.
– @PathVariable Integer id: Extrai o valor de id da URL.
– Chama bairroService.bairroId(id) para buscar o Bairro
correspondente.
– Retorna a entidade Bairro encontrada.
• @DeleteMapping("/{id}") public String apagaBairroId(@PathVariable
Integer id):
– Mapeia requisições HTTP DELETE para /bairros/{id}.
– Chama bairroService.apagaId(id) para deletar o Bairro.
– Retorna uma mensagem de string confirmando a exclusão.
• @PostMapping("") public String salvaDadosBairro(@RequestBody Bairro
bairro):
– Mapeia requisições HTTP POST para /bairros.
– @RequestBody Bairro bairro: Indica que o corpo da requisição HTTP
(esperado em JSON) deve ser desserializado diretamente em um objeto
da entidade Bairro. Diferentemente do CidadeController que usava
um DTO (CidadeForm), este endpoint espera a própria entidade Bairro
no corpo da requisição para criação.
– Chama bairroService.salvarBairro(bairro) para persistir a nova
entidade Bairro.
– Retorna uma mensagem de string confirmando o cadastro.
• @PutMapping("/{id}") @Transactional public String
atualizaDadosBairro(@PathVariable Integer id, @RequestBody Bairro
bairro):
– Mapeia requisições HTTP PUT para /bairros/{id}.
– @PathVariable Integer id: Extrai o ID do Bairro a ser atualizado da
URL.
– @RequestBody Bairro bairro: Obtém os novos dados do Bairro do
corpo da requisição, também esperando a entidade Bairro diretamente.
– @Transactional: Garante que a operação de atualização seja executada
dentro de uma transação do banco de dados, promovendo a
atomicidade.
– Chama bairroService.editaBairro(bairro, id) para atualizar a
entidade Bairro.
– Retorna uma mensagem de string indicando o sucesso da atualização.
Propósito e Uso:
BairroController serve como a interface RESTful para as operações
relacionadas à entidade Bairro. Ele recebe requisições HTTP, delega a lógica de
processamento para BairroService e retorna respostas apropriadas para o cliente.
Uma diferença notável em relação ao CidadeController é que os métodos de criação
(@PostMapping) e atualização (@PutMapping) deste controlador recebem a entidade
Bairro diretamente no @RequestBody, em vez de um DTO específico como
CidadeForm. Embora isso possa ser mais simples para entidades sem lógica complexa
de entrada ou validação, o uso de DTOs é geralmente preferido para melhor
desacoplamento e controle sobre os dados expostos e recebidos pela API.

6. Configurações
As classes de configuração no Spring Boot são usadas para personalizar o
comportamento da aplicação, definir beans, configurar a segurança, entre outros
aspectos.

6.1. Configuração CORS CorsConfig.java


A classe CorsConfig é responsável por configurar o Cross-Origin Resource
Sharing (CORS) para a aplicação Spring Boot. CORS é um mecanismo de segurança que
permite ou restringe requisições de recursos de um domínio (origem) diferente
daquele do servidor que hospeda o recurso. Isso é crucial quando se tem um frontend
(como uma aplicação Angular, React, Vue.js) rodando em um domínio/porta diferente
do backend da API.
package com.fatec.comercio.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration // Indica que esta é uma classe de configuração do Spring


public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // Aplica a configuração CORS a todos
os caminhos (endpoints) da API
.allowedOrigins("http://localhost:4200") // Permite
requisições originadas do frontend Angular (rodando em localhost:4200)
.allowedMethods("GET", "POST", "PUT", "DELETE",
"OPTIONS") // Especifica os métodos HTTP permitidos
.allowedHeaders("*") // Permite todos os tipos de
cabeçalhos na requisição
.allowCredentials(true); // Permite o envio de
credenciais (como cookies ou tokens de autorização) nas requisições
}
}

Anotações e Interface:
• @Configuration: Esta anotação marca a classe CorsConfig como uma fonte de
definições de beans e configurações para o contêiner Spring. O Spring irá
processar esta classe para aplicar as configurações nela definidas.
• implements WebMvcConfigurer: Ao implementar a interface
WebMvcConfigurer, a classe ganha a capacidade de personalizar a configuração
do Spring MVC. Esta interface fornece métodos de callback que podem ser
sobrescritos para ajustar diversos aspectos do framework MVC, incluindo o
CORS.
Método addCorsMappings:
• @Override public void addCorsMappings(CorsRegistry registry) :
– Este método é sobrescrito da interface WebMvcConfigurer e é o local
onde as regras de CORS são definidas.
– O parâmetro CorsRegistry registry é fornecido pelo Spring MVC e
permite registrar mapeamentos CORS específicos.
– registry.addMapping("/**"):
• Este chamado configura o CORS para ser aplicado a todos os
caminhos (endpoints) da aplicação. O padrão /** é um curinga
que corresponde a qualquer rota na API.
– .allowedOrigins("http://localhost:4200"):
• Especifica quais origens (domínios) têm permissão para fazer
requisições cross-origin para esta API.
• Neste caso, apenas requisições vindas de
http://localhost:4200 são permitidas. Isso é comum em
desenvolvimento, onde o frontend (por exemplo, uma aplicação
Angular) está rodando localmente na porta 4200.
• Para ambientes de produção, este valor seria alterado para o
domínio real do frontend.
– .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") :
• Define quais métodos HTTP são permitidos nas requisições
cross-origin.
• Os métodos listados (GET, POST, PUT, DELETE, OPTIONS) cobrem as
operações CRUD típicas e o método OPTIONS (usado para
requisições de “preflight” em CORS).
– .allowedHeaders("*"):
• Permite que as requisições cross-origin incluam quaisquer
cabeçalhos. O * é um curinga para todos os cabeçalhos.
• Pode-se restringir a cabeçalhos específicos se necessário por
segurança.
– .allowCredentials(true):
• Indica se o navegador deve enviar credenciais (como cookies,
tokens de autorização HTTP) junto com as requisições cross-
origin.
• Quando definido como true, o servidor informa ao navegador
que ele pode processar a requisição mesmo que ela inclua
credenciais. Se definido como false (o padrão se não
especificado), as credenciais não seriam enviadas ou seriam
ignoradas.
• Importante: Se allowCredentials(true) for usado,
allowedOrigins não pode ser *. Uma origem específica deve ser
definida.
Propósito e Uso:
Sem uma configuração CORS adequada, os navegadores modernos bloqueariam as
requisições feitas por um frontend (ex: http://localhost:4200) para um backend
API rodando em uma origem diferente (ex: http://localhost:8080, que é a porta
padrão para aplicações Spring Boot). A classe CorsConfig garante que a API Spring
Boot envie os cabeçalhos CORS corretos nas respostas HTTP, instruindo o navegador a
permitir essas requisições.
Esta configuração é essencial para o desenvolvimento e funcionamento de aplicações
web modernas onde o frontend e o backend são desacoplados e servidos de diferentes
origens.

7. Como Executar a API


Esta é uma aplicação Spring Boot padrão. Para executá-la, você geralmente precisará
de:
1. Java Development Kit (JDK): Versão 8 ou superior (verifique o pom.xml ou
build.gradle do projeto para a versão específica do Java e do Spring Boot, se
disponível nos arquivos do projeto completo).
2. Maven ou Gradle: Dependendo de como o projeto foi configurado para
gerenciamento de dependências e build (informação não presente nos
arquivos fornecidos).
3. Banco de Dados: A aplicação interage com um banco de dados relacional. As
configurações de datasource (URL do banco, usuário, senha) normalmente
residem no arquivo application.properties ou application.yml na pasta
src/main/resources (não fornecido). Certifique-se de que o banco de dados
esteja configurado e acessível conforme definido no projeto.
Passos Típicos para Execução (assumindo Maven e um projeto Spring Boot
padrão):
1. Certifique-se de que o projeto completo esteja disponível, incluindo arquivos
de build (como pom.xml) e configuração.
2. Navegue até o diretório raiz do projeto no terminal.
3. Compile o projeto e baixe as dependências: mvn clean install (ou mvn
package).
4. Execute a aplicação: java -jar target/nome-do-artefato.jar. O nome-do-
artefato.jar será o nome do arquivo JAR gerado na pasta target após a
compilação (por exemplo, comercio-0.0.1-SNAPSHOT.jar).
Alternativamente, se estiver usando uma IDE como IntelliJ IDEA, Eclipse ou VS
Code com as extensões Java e Spring Boot apropriadas, você pode geralmente
importar o projeto (se for um projeto Maven ou Gradle) e executar a aplicação
diretamente pela IDE. A IDE localizará a classe principal anotada com
@SpringBootApplication (não fornecida, mas tipicamente presente na raiz do pacote
da aplicação, como ComercioApplication.java) e permitirá executá-la.

8. Referências
Os arquivos de código-fonte analisados neste manual são a principal referência
para a API:
• Uf.java
• Sexo.java
• Cidade.java
• Cep.java
• Bairro.java
• UfRepository.java
• SexoRepository.java
• CidadeRepository.java
• CepRepository.java
• BairroRepository.java
• UfService.java
• SexoService.java
• CidadeService.java
• BairroService.java
• CidadeForm.java
• UfController.java
• SexoController.java
• CidadeController.java
• BairroController.java
• CorsConfig.java
EXERCÍCIO
Construa a estrura que ainda falta com base na imagem. Lembre-se que ainda
não conseguiremos fazer o Mapeamento N x N. Teste todos os mapeamentos no
Postman.

Você também pode gostar