Um Projeto Spring Boot - P5.1
Tags: java, spring, rest, tutorial
Published: 2022-12-20 15:53:55

Faala pessoal! Tudo bem? 

Estou de volta para mais um post sobre o projeto Rest API e para relembrar sobre o que já foi mostrado, deixo essa lista dos articles já publicados:

- [Primeiro post](https://dev.to/devs-jequie/um-projeto-rest-api-2pc9)
- [Segundo post](https://dev.to/fllaviacorreia/configurando-o-ambiente-de-desenvolvimento-4a7h)
- [Terceiro post](https://dev.to/fllaviacorreia/um-projeto-spring-boot-p1-nii)
- [Quarto post](https://dev.to/fllaviacorreia/um-projeto-spring-boot-p4-5931)

---

## Ferramentas utilizadas
Para o post de hoje, irei falar com vocês sobre persistência de dados, nessa situação estarei utilizando o [Jakarta Persistence API](https://jakarta.ee/specifications/persistence/3.0/), [Spring Data JPA](https://spring.io/projects/spring-data-jpa) e [FlyWay (FW)](https://flywaydb.org/documentation/). É nesse ponto que iremos utilizar o banco de dados relacional MySQL, mas fica a seu critério se adaptar e utilizar o seu DB preferido.

---

- Adicione o Spring Data JPA, FlyWay Migration e o MySQL Driver ao projeto;
_nesse ponto aqui, eu tive um problema com o drive do MySQL, então no pom.xml alterei a dependência do driver para:_

`<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
</dependency>`

---

## Configurando a conexão com o banco de dados
- Adicione as informações do banco de dados no arquivo _application.properties_ que está dentro do pacote resources:

![dados no arquivo application.properties](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/knvyd2hihs3u3j6b9w38.png)

---

## Como gerar migrations
- Crie dentro de src/main/resources uma pasta 'db' e uma subpasta 'migration'. 

É nelas que estarão todos os arquivos referentes ao banco de dados, como os scripts de criação/alteração/deleção de tabelas, colunas, etc.. 

Por padrão, o FW só lê os scripts com nome em determinado padrão, por padrão o FW percebe: 
   1. arquivos iniciados com 'V', maiúsculo mesmo, e ai a identificação do arquivo fica a seu critério, com índice (V0001) ou data e hora (V20221213213045 - meu formato aqui está YYYY/MM/DD-HH:MM:SS)(eu vou seguir com a primeira opção);
   2. é inserido 2 underscore (__) após a versão do arquivo;
   3. é inserido a descrição do arquivo junto com a extensão .sql (p.e. create-table-books.sql)

Então no final fica: 
- V0001__create-table-books.sql

ou

- V20221213213045__create-table-books.sql

---

OBS.: Se o projeto estiver rodando, quando criar o arquivo com a extensão .sql o devtools vai fazer o seu papel de reiniciar o servidor e o FW vai rodar o script vazio e isso vai gerar uma mudança no DB e ficar registrado na tabela referente ao FW que foi criada, a com nome _flyway_schema_history_. 

É nessa tabela que são guardadas as infos referentes ao banco, como por exemplo quais os schemas rodados.

Então, eu recomendo que, com o servidor inativo, crie os arquivos com a versão e extensão e, só depois de tudo certo, com o DDL inserido no arquivo, inicie o servidor.

Você pode também fazer isso com o servidor ativo, ai pode criar o arquivo com o nome (ex. create-table-books.sql) e só depois alterar o nome do arquivo para o padrão.

---

## Modificando a Model de Editora e criando a migration 
Como iniciei com o Model de Editora, vou criar o DDL de editora da seguinte forma:

- criei o arquivo V0001__create-table-publishing-companies.sql

- adicionei o schema:

`CREATE TABLE IF NOT EXISTS publishing_companies(
id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(200) NOT NULL,
city VARCHAR(50) NOT NULL,
state VARCHAR(5) NOT NULL,
country VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
)`

- alterei a model de editora para garantir a persistência de dados e indicar que é uma table do banco:

![inclusão da persistência de dados v1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pl5aacq9166ei34igpmo.png)

a. nas linhas 13 e 20 eu chamei mais uma funcionalidade do Lombok que é a geração de _hash code_ e _equals_, se não tivesse o código iria fica muito poluído:
![equals e hash code padrão](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k1fof8tb7ylqerb1k1vy.png)

b. a linha 16 está indicando que a classe é uma entidade no banco de dados e na linha 17 referencio a tabela do DB com o nome "publishing_companies", caso o nome da tabela  fosse equivalente ao do Model, então não precisaria utilizar o Table(name = "name_table_reference")

c. na linha 21 estou indicando que o atributo "id" é referencia à coluna ID da tabela;

d. na linha 22 estou indicando que o ID da tabela será gerado a partir do padrão do banco, por isso a passagem do _strategy_ por parâmetro.

e. repare que nos atributos seguintes não coloquei nenhuma anotação para identificar que são colunas na tabela publishing_companies, isso acaba se tornando opcional, nesse caso, porque o nome é igual. Caso não fosse esse o caso, passaria a anotação @Column(name = "nome_column")

f. se deseja entender melhor sobre @Entity e @Table, tem uma disussão no Stack Overflow sobre esse assunto [aqui](https://stackoverflow.com/questions/18732646/name-attribute-in-entity-and-table).

---

## Modificando o controlador
- modifiquei o GET de editora para fazer uma busca no banco de dados:

![publishing company controller](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/463as2xlj5furj2kqo1c.png)


a. criei um atributo do tipo EntityManager para gerenciar o banco

b. a partir dele, chamei o método para criar uma query e a busca foi feita usando [JPQL](https://www.tutorialspoint.com/pg/jpa/jpa_jpql.htm) com o formato da classe de editora.

c. o resultado é convertido em uma lista do tipo do model de editora e retornado para quem solicitou a busca.

---

Como resultado, após iniciar o servidor, tive:
### 1 resultado no DB: 
a. duas tables criadas
![tables no banco](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcvo0rd42s3d62cpenne.png)

b. a table do Flyway com 1 resultado e a column success = 1
![table do flyway no banco](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wbocmn7dks5kmckm7anl.png)

c. a table de editora criada com o nome: publishing_companies e todos os atributos passados no DDL

![table de editora](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjkgzbmhscsn2t4wacft.png)

### 2 resultado no Postman:

![resultado no Postman](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zlmz3zgarkze2t30y241.png)


---

Bom pessoal, por enquanto é isso.

Na próxima publicação, vou trazer um tutorial sobre salvamento, deleção e alteração de dados.

Se tiver alguma dúvida, deixa nos comentários, críticas e sugestões também são bem vindas.

Até mais!