Entre para a LISTA VIP da Black Friday

00

DIAS

00

HORAS

00

MIN

00

SEG

Clique para saber mais
Alura > Cursos de Programação > Cursos de Kotlin > Conteúdos de Kotlin > Primeiras aulas do curso API REST com Kotlin e Spring Boot: Camada de persistência

API REST com Kotlin e Spring Boot: Camada de persistência

Spring Data JPA - Apresentação

Boas-vindas ao segundo curso da formação de API REST com Kotlin. Meu nome é Rodrigo Ferreira e eu serei seu instrutor.

Audiodescrição: Rodrigo Ferreira é uma pessoa de pele clara, com olhos castanhos e cabelos também castanhos e lisos. Veste uma camiseta cinza. Ao fundo, uma parede clara.

Essa é a segunda parte da formação focada na construção de APIs REST com Kotlin e Spring Boot.

Na primeira etapa da formação, criamos a API, incluindo o projeto, controlers, camada de serviço, DTOs, configurações e tratamentos de erros, validações, entre outros assuntos. Nesse curso, daremos continuidade no mesmo projeto, portanto, recomendamos que você primeiro conclua o primeiro curso da formação.

No primeiro curso focamos na parte web, agora nosso foco será na persistência, para isso, vamos incorporar um banco de dados na aplicação. Anteriormente, simulamos um banco de dados em memória com uma lista fictícia de dados. Cada vez que reiniciávamos o servidor, perdíamos as informações. Agora, implementaremos uma camada de persistência real com um banco de dados.

Utilizaremos o Spring Data JPA, o módulo do Spring Boot para trabalhar com persistência, com a JPA. Ensinaremos como configurá-la, como adicionar o banco de dados ao projeto e efetuar as configurações.

Faremos o mapeamento das entidades, criaremos as interfaces repository que fazem a camada de persistência e adaptaremos o código, que usava lista em memória, para utilizar o repository e acessar o banco de dados propriamente dito.

Trabalharemos com migrações utilizando o Flyway para gerir a evolução do esquema do banco de dados. Trata-se de um tema muito relevante e utilizado atualmente no mercado.

Lidaremos também com caches, otimizações e entender como funciona no Spring. Além disso, aprenderemos recursos de persistência, como paginação, ordenação e projections para elaborar algumas queries mais sofisticadas.

Esse é o conteúdo que aprenderemos nesse segundo curso da formação. Complementaremos a API, agora com foco na camada de persistência.

Esperamos que você goste do projeto e aprenda muito. Te esperamos no primeiro vídeo!

Spring Data JPA - Configurando o Spring Data JPA

Com o projeto aberto no IntelliJ , configuraremos a camada de persistência, precisamos adicionar os módulos de persistência e do banco de dados.

No primeiro curso da formação, como o foco era na parte web, quando geramos o projeto utilizando o site do Spring Initializer, selecionamos apenas as dependências web, sem adicionar as dependências de persistência.

Configurando o Spring Data JPA

Sendo assim, abrimos o arquivo póm.xml. Precisamos adicionar duas dependências, para facilitar esse processo, copiamos a última dependência criada, entre as linhas 48 e 52, e colamos logo abaixo duas vezes.

Agora, faremos as alterações necessárias. Primeiro, apagamos a tag <scope>. Uma das dependências que precisamos é o módulo da JPA do Spring Boot, o Spring Data JPA. Mantemos o <groupId> como está e em <artifactId>, apagamos o test e acrescentamos -data-jpa. Assim, já será baixada todas as dependências da JPA e do Hibernate como implementação da JPA.

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

A outra dependência que precisaremos é do driver do banco de dados que utilizaremos na aplicação. Para não perdermos tempo com configuração de banco de dados, utilizaremos o h2, um banco de dados em memória.

No entanto, se você tiver no seu computador o MySQL, Postgre ou qualquer outro banco já instalado e funcionando corretamente, você pode colocar a dependência do seu banco de dados.

Na segunda dependência que colamos, dentro de <groupId>, passamos com.h2database. Em seguida, em <artifactId>, apagamos todo o código que está entre essa tag e passamos h2.

<dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
</dependency>

Essas são as duas dependências que precisamos, o Spring Data JPA e o driver do banco de dados, que nesse caso é o h2.

Para verificar se as dependências foram baixadas, na lateral superior direita da tela, clicamos no ícone nomeado "Maven". Feito isso, abre uma janela. Nela, selecionamos o projeto e depois clicamos no botão "Reload All Maven Projects", localizado na lateral superior esquerda da janela, identificado por duas setas que formam um círculo.

Depois clicamos na pasta "Dependencies" e verificamos se foi baixado. Nessa caso, notamos que foi baixado o h2 e o Data JPA.

Já adicionamos o módulo do JPA e o módulo do banco de dados. O próximo passo é fazer as configurações do banco de dados. Precisamos informar ao Spring Boot onde está o endereço do banco de dados, usuário, senha e outras informações de acesso.

Essas configurações ficam num arquivo que até então não mexemos nele, pois não houve necessidade. Para abri-lo, acessamos as pastas "src > main > resoueces" e abrimos o arquivo application.properties.

Nele, ficam as configurações do projeto, portanto, as configurações de persistência também. Porém, por padrão esse arquivo vem como properties, mas você pode utilizar também um arquivo com a extensão yml, que tem outra maneira de escrever as propriedades.

Como essa é uma opção mais usada atualmente, clicamos no arquivo com o botão direito e depois em "Refactor > Rename". Renomeamos para application.yml e clicamos no botão "Refactor".

Em resumo, você pode trabalhar com o arquivo .properties, que tem o formato chave-valor. Nele há o nome da propriedade igual ao valor, na linha de baixo outra propriedade igual o valor da propriedade. Cada linha você tem uma propriedade que é chave-valor, tipo um mapa do Java.

A outra opção é trabalhar com o arquivo yml que é o arquivo de hierarquia. Há uma propriedade filha, nela, colocamos dois pontos e na linha de baixo, utilizando o tab, adicionamos as dependências filhas.

Fica a seu critério definir o formato. Usaremos o yml, pois é o formato mais comum no mercado.

Spring Data JPA - Mapeamento das entidades JPA

Declaramos as dependências da JPA e do Banco de Dados e fizemos as configurações no Application YAML. O próximo passo é fazer os mapeamentos das entidades da JPA.

Mapeando as entidades JPA

Com o projeto aberto, acessamos as pastas "src > kotlin". Dentro do pacote raiz br.com.alura.forum tem o pacote model, onde encontramos as classes de domínio que representam os recursos da API. Essas são as classes que vamos transformaremos em entidades da JPA.

O foco desse curso não é JPA, mas sim na parte do Spring Boot e Kotlin. Portanto, faremos o mapeamento, sem nos aprofundar em JPA.

Caso você não conheça JPA ou tenha interesse em se aprofundar mais nesse tema, sugerimos um curso da Alura sobre esse tema em especídifco.JPA. É importante que você entenda como é seu funcionamento e mapeamento.

Tópico.kt

Começamos abrindo o arquivo Tópico.kt, a principal do curso, pois precisamos transformá-la em uma entidade. Para isso, na linha acima da classe, passamos notação @Entity, que vem do pacote javax.persistence. Com isso, a JPA já sabe que a classe Topico() é uma entidade da JPA. Logo, está mapeando uma tabela no banco de dados.

Além do @Entity, no atributo id que representa a chave primária, na linha abaixo da classe, passamos a notação @Id e @GeneratedValue(). Isso ocorre, pois não é a aplicação que vai gerenciar os ids e sim o próprio banco de dados. Nos parênteses, passamos o atributo strategy igual a GenerationType.IDENTITY.

O atributo curso, como é um relacionamento, precisamos transformá-lo em entidade. Quando temos uma entidade se relacionando com outra entidade, precisamos definir a cardinalidade. De Tópico para Curso, a cardinalidade é @ManyToOne, então, escrevemos na linha acima de val curso. Fazemos o mesmo procedimento com val autor que é o relacionamento com usuário.

Já o atributo status, na linha acima passamos @Enumerated() para que não salve no banco a coluna como sendo a ordem das constantes. Nos parênteses escrevemos value igual à EnumType.STRING. Desta forma, será salvo no banco de dados o nome da constante do status, como: não respondido, finalizado, entre outros, ao invés de salvar a ordem.

Por fim, em respostas que também é um relacionamento, passamos na linha acima @OneToMany(), que significa um para muitos, um tópico tem várias respostas. Dessa forma, na classe resposta, também estará mapeada no Tópico.

Isso significa que temos um relacionamento bidirecional. Então, precisamos informar que esse relacionamento está sendo mapeado em ambos os lados. Portanto, nos parênteses de @OneToMany passamos mappedBy igual a tópico, entre aspas duplas, pois é o nome do atributo na classe resposta.

@Entity
data class Topico(
            @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
            var id: Long? = null,
            val titulo: String,
            val mensagem: String,
            val dataCriacao: LocalDateTime = LocalDateTime.now(),
            @ManyToOne
            val curso: Curso, @ManyToOne
            val autor: Usuario,
            @Enumerated(value = EnumType.STRING)
            val status: StatusTopico = StatusTopico.NAO_RESPONDIDO,
            @OneToMany (mappedBy = "topico")
            val respostas: List<Resposta> = ArrayList()

Feito isso a entidade Topico() está corretamente mapeada. Agora, vamos abrir a classe Resposta.kt, que també se tornará uma entidade.

Resposta.kt

Na linha acima, como feito anteriormente, passamos @Entity. Para facilitar, acessamoso Topico.kt, copiamos o @Id e @GeneratedValue e colamos na linha abaixo da classe. Depois, na linha acima de autor, passamos @ManyToOne, assim como em topico.

@Entity
data class Resposta(
            @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
            val id: Long? = null,
            val mensagem: String,
            val dataCriacao: LocalDateTime = LocalDateTime.now(), @ManyToOne I
            val autor: Usuario, @ManyToOne
            val topico: Topico,
            val solucao: Boolean
)

Em seguida, abrimos o arquivo Curso.kt. Repetimos o mesmo procedimento passando @Entity acima da classe e abaixo passando o @Id e @GeneratedValue(). Ficando dessa forma:

@Entity
data class Curso (
            @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
            val id: Long? = null,
            val nome: String,
            val categoria: String

Por fim, temos a classe Usuario(), que passamos @Entity logo na linha acima.

@Entity
data class Usuario(
            @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
            val id: Long? = null,
            val nome: String,
            val email: String

Assim, concluímos o mapeamento das entidades. Agora o JPA sabe que essas classes representam entidades da JPA que possuem tabelas no banco de dados.

Lembrando que não nos aprofundamos nas notações, pois esse é um detalhe específicos de JPA. Caso você não conheça ou tenha dúvidas, recomendamos fazer a formação de JPA.

No próximo vídeo, migraremos o código que estava trabalhando com dados em memória para utilizar o banco de dados.

Sobre o curso API REST com Kotlin e Spring Boot: Camada de persistência

O curso API REST com Kotlin e Spring Boot: Camada de persistência possui 132 minutos de vídeos, em um total de 46 atividades. Gostou? Conheça nossos outros cursos de Kotlin em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Kotlin acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas