Alura > Cursos de Programação > Cursos de Java > Conteúdos de Java > Primeiras aulas do curso Java: persistência de dados e consultas com Spring Data JPA

Java: persistência de dados e consultas com Spring Data JPA

Evoluindo o projeto ScreenMatch - Apresentação

Iasmin: Olá! Tudo bem? Eu sou a Iasmin Araújo, faço parte do Scuba Team na escola de Programação, e te dou boas-vindas a mais um curso de Java na Alura!

Audiodescrição: Iasmin se descreve como uma mulher branca, de cabelo longo, liso e castanho-escuro e olhos verdes. Ela veste uma camisa preta e está sentada em um quarto com iluminação azul ao fundo, um guarda-roupa à esquerda e uma cama à direita.

Porém, não estou sozinha. Mais uma vez, estou com minha parceria, a rainha do Java: a Jacque!

Jacqueline: Ótimo! Obrigada pela linda introdução, Iasmin. Eu sou a Jacqueline Oliveira, engenheira de software e instrutora aqui na Alura!

Audiodescrição: Jacqueline se descreve como uma mulher de pele branca, com cabelos longos, lisos e loiros e olhos castanho-escuros. Ela veste uma blusa preta e também está sentada em um escritório com iluminação azul ao fundo, e uma estante com enfeites à direita.

Público-alvo

Iasmin: Este conteúdo é para você que já está acompanhando a nossa formação de OO, concluiu o primeiro curso desta formação, sobre streams e lambdas, e deseja continuar aprendendo Java conosco e se aventurar no mundo da persistência de dados.

O que vamos aprender?

Jacqueline: Neste curso, vamos conhecer o banco de dados relacional PostgreSQL, vamos modelar classes para serem salvas no banco, utilizando o Spring Data JPA, que tem várias anotações, as quais iremos conhecer.

Também vamos mapear relacionamentos entre as entidades, seja um relacionamento de um para muitos ou muitos para um. Vamos salvar informações no banco e recuperá-las, realizando diversos tipos de consultas, utilizando JPQL.

Temos um spoiler de algo muito interessante que vamos fazer. Não vamos revelar o recurso, mas daremos uma pista: vamos consumir a API do ChatGPT e integrá-la com uma inteligência artificial.

Iasmin: Vamos explorar tudo isso no projeto ScreenMatch, que você já conhece. Trata-se de um site de streaming de filmes e séries. Continuaremos com um projeto de linha de comando, mas agora vamos evoluir esse projeto, adicionando mais opções para escolha.

Podemos buscar séries na web, assim como na nossa própria aplicação, no nosso próprio banco de dados. Vamos buscar séries, episódios, criar vários filtros e muito mais.

Jacqueline: Além disso, como foi muito solicitado nos depoimentos e feedbacks, teremos desafio surpresa. Haverá um desafio em um contexto diferente do ScreenMatch, para que você possa praticar e consolidar o conhecimento adquirido no curso.

Iasmin: Lembre-se de que você tem o apoio tanto do fórum quanto da comunidade do Discord, então sinta-se à vontade para compartilhar todas as suas dúvidas ou sugestões!

Aproveite todos os recursos que temos à disposição. Temos vídeos, documentações extra, entre outros. Fique à vontade para estudar tudo o que puder, para evoluir bastante em Java.

Jacqueline: Pegue seu café ou sua água e junte-se à nossa maratona!

Evoluindo o projeto ScreenMatch - Evoluindo nossa aplicação Java

Iasmin: Vamos prosseguir com o desenvolvimento da aplicação ScreenMatch? No curso anterior, trabalhamos bastante com streams e listas. Agora, vamos continuar o desenvolvimento levando em consideração várias séries. Antes, focamos principalmente nos episódios e temporadas de uma única série. Agora vamos analisar dados de múltiplas séries.

Evoluindo nossa aplicação Java

Nosso projeto está muito semelhante ao anterior, porém, optamos por separá-lo em alguns métodos. Nós criamos uma modularização e agora temos os métodos buscarSerieWeb(), getDadosSerie() e buscarEpisodioPorSerie(). Deixamos um pouco de lado a parte dos streams e das listas, pois o nosso foco agora é um pouco diferente.

Jacqueline: Ao longo do curso, tanto nos anteriores quanto o imediatamente anterior a este, trabalhamos conceitos do Java para chegar ao momento de evoluir a nossa aplicação.

Trabalhamos com questões de buscas e listas, mas o objetivo do nosso projeto é que essa aplicação se transforme em uma API. Queremos começar a disponibilizar para o nosso público esses dados que hoje buscamos de terceiros. Portanto, o nosso desenvolvimento está sendo feito de maneira incremental para que isso aconteça.

Iasmin: Vamos executar o nosso projeto para verificar como ele está funcionando. Ao clicar no botão "Run" na barra de menu superior à direita, o botão verde de reprodução, será aberto o terminal e exibido o nosso menu.

Temos as opções: "1 - Buscar séries"; e "2 - Buscar episódios". Vamos escolher a opção 1 e buscar a série "The Boys". Com isso, serão retornados os dados da série.

DadosSerie[titulo=The Boys, totalTemporadas=4, avaliacao=8.7]

Após isso, terminamos a execução. Se quisermos buscar os episódios de "The Boys", teremos que executar o projeto mais uma vez, selecionar a opção 2 e, em seguida, buscar os episódios. Portanto, vamos digitar novamente "The Boys", e teremos como resultado os dados detalhados.

Podemos aprimorar essa aplicação, não é mesmo, Jacque?

Estrutura de repetição

Jacqueline: Para começar, podemos trabalhar com essa estrutura de repetição. A ideia é buscar várias séries primeiro, e depois decidir qual episódio queremos buscar. Vamos criar uma repetição para que a aplicação seja finalizada somente quando a pessoa usuária decidir.

Iasmin: Já temos isso previamente configurado. Temos a opção "0" para sair. O que faremos será criar uma condição de parada. Para isso, usaremos o while na linha 25 do arquivo Principal.java, para informar enquanto a opção for diferente de zero (while(opcao "= 0)).

Em seguida, vamos abrir chaves e fechá-las logo após o switch.

Principal.java:

while(opcao != 0) {
    var menu = """
            1 - Buscar séries
            2 - Buscar episódios
            3 - Listar séries buscadas

            0 - Sair                                 
            """;

    System.out.println(menu);
    var opcao = leitura.nextInt();
    leitura.nextLine();

    switch (opcao) {
        case 1:
            buscarSerieWeb();
            break;
        case 2:
            buscarEpisodioPorSerie();
            break;
        case 0:
            System.out.println("Saindo...");
            break;
        default:
            System.out.println("Opção inválida");
    }
}

Agora, mudaremos o local da declaração de opcao da linha 35. Em vez de ficar dentro do bloco while, ela ficará do lado de fora, pois precisamos dessa variável para a condição do while.

Iremos instanciá-la com o valor "-1" na linha 25, apenas para entrar no while uma única vez, e depois a pessoa usuária é quem irá modificá-la.

public void exibeMenu() {
    var opcao = -1;
    while(opcao != 0) {
        
        // código omitido
        
        System.out.println(menu);
        opcao = leitura.nextInt();
        leitura.nextLine();
        
        // código omitido

Agora temos um loop. A pessoa usuária pode ficar o quanto desejar, mas precisamos fazer com que haja uma lista de séries e que essa lista seja exibida, ou não faz sentido ter um loop.

Adicionando uma lista de séries

Portanto, precisaremos de uma lista de séries para que possamos adicioná-las. Vamos declarar essa lista após API_KEY na linha 22. Teremos uma lista privada (private List<>) de DadosSerie chamada dadosSeries, e vamos instanciar essa lista usando new ArrayList<>().

private List<DadosSerie> dadosSeries = new ArrayList<>();

Agora, toda vez que buscarmos uma série na web, vamos adicioná-la à lista. Então, no método buscarSerieWeb(), vamos digitar dadosSeries.add() e passar os dados buscados.

private void buscarSerieWeb() {
    DadosSerie dados = getDadosSerie();
    dadosSeries.add(dados);
    System.out.println(dados);
}

Criando o método listarSeriesBuscadas()

Podemos imprimir essa lista, concorda, Jacque?

Jacqueline: Perfeito, é uma boa ideia criar um novo método para listar as séries que acabamos de adicionar à lista.

Iasmin: Então, primeiramente, vamos criar uma opção no menu que será para listar as séries buscadas ("3 - Listar séries buscadas").

var menu = """
        1 - Buscar séries
        2 - Buscar episódios
        3 - Listar séries buscadas

        0 - Sair                                 
        """;

Feito isso, também precisaremos declarar no switch o case 3, que será para chamar este método de listar. Então, vamos utilizar case 3: seguido de listarSeriesBuscadas() abaixo.

switch (opcao) {
    case 1:
        buscarSerieWeb();
        break;
    case 2:
        buscarEpisodioPorSerie();
        break;
    case 3:
        listarSeriesBuscadas();
        break;
    case 0:
        System.out.println("Saindo...");
        break;
    default:
        System.out.println("Opção inválida");
}

Agora, precisamos criar esse método que ainda não existe. Vamos copiar a assinatura do método, lembrando também de usar o break na última linha do case, algo crucial no switch case.

O método listarSeriesBuscadas() será privado (private), pois queremos fortalecer o encapsulamento. Então, teremos private void listarSeriesBuscadas() ao final do código.

A única função deste método será imprimir os dados da lista dadosSeries. Sendo assim, no escopo do método, vamos executar dadosSeries.forEach(System.out::println).

private void listarSeriesBuscadas() {
    dadosSeries.forEach(System.out::println)
}

Jacqueline: Vamos executar a aplicação para verificar o que acontece?

Lembre-se: sempre focamos em boas práticas. Como é uma única linha de código, isso poderia ter sido incluído no case. No entanto, nosso código fica muito mais legível quando separamos por métodos e deixamos descrito exatamente o que acontece.

Além disso, pode ser que em algum momento queiramos alterar como essas séries serão listadas. Então, definitivamente não é uma boa prática lançar todo esse código dentro do case.

Criamos um novo método privado, para que apenas essa classe possa chamá-lo e não a classe ScreenmatchApplication que chama a principal. Queremos que a classe externa possa chamar apenas o método exibeMenu(). Então, todos os outros métodos desta classe são privados.

Estamos sempre trabalhando não só o que vamos fazer, mas a melhor maneira possível de fazer, usando boas práticas de desenvolvimento.

Testando o código

Iasmin: Agora vamos testar e utilizar essas duas práticas.

Após executar a aplicação, temos as três opções no terminal e vamos buscar várias séries. Para isso, selecionamos a opção 1 e pesquisamos, por exemplo, "Never Have I Ever".

Jacqueline: A próxima série pode ser "Grey's Anatomy".

Iasmin: Vamos buscar só mais uma, a série "The Boys". Assim, temos três séries. Vamos tentar listar essas séries agora. Para isso, digitamos 3. Como resultado, temos o seguinte:

DadosSerie[titulo=Never Have I Ever, totalTemporadas=4, avaliacao=7.9]
DadosSerie[titulo=Grey's Anatomy, totalTemporadas=19, avaliacao=7.6]
DadosSerie[titulo=The Boys, totalTemporadas=4, avaliacao=8.7]

Já conseguimos buscar várias séries!

Conclusão

Jacqueline: Perfeito. Agora, podemos listar como um próximo passo buscar mais dados dessa série, porque se vamos disponibilizar isso para nossas pessoas usuárias, sabemos que no OMDB temos mais informações dessa série que poderíamos utilizar, além de título, total de temporadas e avaliação. Temos uma série de coisas que podem ser retornadas na mesma requisição.

Dito isso, poderíamos pegar alguns outros elementos, por exemplo, as categorias e a imagem do pôster, para que quando o front-end consumir essa API, ele mostre essa imagem. A sinopse também é interessante, para quem consultar saber sobre o que é a série.

O que você acha, Iasmin?

Iasmin: Acho que o nome dos atores também seria interessante, Jacque.

Jacqueline: Boa ideia, Iasmin!

Iasmin: Nós já sabemos como fazer, estudamos bastante sobre isso no primeiro curso, que seria buscar informações no arquivo JSON. De uma forma muito semelhante ao que já foi feito, nós desafiamos você a fazer isso!

Trabalharemos em segundo plano e na próxima aula discutiremos o que foi realizado.

Jacqueline: Exatamente. Na sequência, você perceberá que na nossa aplicação já estará mapeado, porém, o desafio é você alterar a modelagem e incluir as informações extra de série!

Evoluindo o projeto ScreenMatch - Modelando categorias e séries

Estamos com a classe DadosSerie modelada conforme o desafio.

DadosSerie.java:

package br.com.alura.screenmatch.model;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosSerie(@JsonAlias("Title") String titulo,
                         @JsonAlias("totalSeasons") Integer totalTemporadas,
                         @JsonAlias("imdbRating") String avaliacao,
                         @JsonAlias("Genre") String genero,
                         @JsonAlias("Actors") String atores,
                         @JsonAlias("Poster") String poster,
                         @JsonAlias("Plot") String sinopse) {
}

A primeira coisa que fizemos foi adicionar a anotação @JsonAlias para cada atributo vindo do OMDB, e criamos os atributos genero, atores, poster e sinopse. Podemos então tentar executar para verificar o que vai acontecer.

Jacqueline: Isso, vamos conferir se já serão exibidos esses atores, os gêneros e até o pôster da série, que será exibido posteriormente para a pessoa usuária.

Modelando categorias e séries

Iasmin: Vamos abrir o arquivo ScreenmatchApplication.java e executar no método main(). Com o terminal aberto, vamos digitar 1 e buscar pela série "The Boys".

Vamos analisar como os dados vieram para nós. Temos o título, o total de temporadas, a avaliação, e a novidade são gênero, atores, o pôster e a sinopse. Conseguimos pegar nossos dados da forma como desejávamos.

Jacqueline: Porém, da mesma forma que fizemos com Episodio, talvez seja necessária uma classe própria para tratar as coisas como precisamos.

O motivo é que o atributo avaliacao vem como string. O genero vem com três itens: ação (Action), comédia (Comedy) e crime (Crime), e ainda está em inglês.

Como vamos mostrar isso para a pessoa usuária? Se ela buscar por categoria, a série vai aparecer em três categorias? Talvez não seja o ideal. Queremos que, por exemplo, somente essa primeira categoria de ação seja a categoria que vai representar a série.

Portanto, precisamos ter uma classe própria chamada Serie, assim como fizemos com Episodio, para representar as informações e tratá-las como de fato vamos querer apresentá-las futuramente para a nossa pessoa usuária.

Criando a classe Serie

Iasmin: Vamos minimizar o terminal e começar a criar a classe Serie. No pacote "model", clicaremos com botão direito e vamos até "New > Java Class". Chamaremos a classe de Serie. Essa será uma classe real, não mais um registro.

A nova classe terá os mesmos atributos que a DadosSerie, então podemos copiar todos esses atributos do arquivo DadosSerie.java e colá-los na classe Serie.java.

Vamos modificar conforme a necessidade, então no lugar de @JsonAlias(), colocaremos private em todos os atributos. Além disso, substituiremos as vírgulas por ponto e vírgula.

Serie.java:

package br.com.alura.screenmatch.model;

public class Serie {
    private String titulo;
    private Integer totalTemporadas;
    private String avaliacao;
    private String genero;
    private String atores;
    private String poster;
    private String sinopse;
}

Agora temos todos os atributos devidamente declarados. Como alguns atributos estão como string e precisaremos mudar, faremos isso agora.

Para avaliacao, não é uma boa ideia deixarmos como String, então vamos converter para Double, da mesma forma que estava em Episodio. Os outros atributos podem permanecer como String, exceto pelo genero.

Se pensarmos no gênero, geralmente identificamos uma série por um gênero específico. Não pensamos em "Friends" como uma série de comédia, drama, romance e vários outros gêneros. Portanto, podemos representar esse gênero como uma categoria, e essa categoria pode ser um enum. Dessa forma, substituiremos String antes de genero por Categoria.

public class Serie {
    private String titulo;
    private Integer totalTemporadas;
    private Double avaliacao;
    private Categoria genero;
    private String atores;
    private String poster;
    private String sinopse;
}

Criando o enum Categoria

Podemos descrever Categoria como um enum. Por que isso é possível?

Sempre que tivermos gêneros, teremos uma lista de constantes que serão os gêneros. Sempre teremos ação, romance, crime, drama, que são coisas fixas. Podemos adicionar à nossa lista, mas não virão coisas muito diferentes disso. Nossa lista será bem estática. Portanto, podemos representar como um enum.

Então, clicaremos com o botão direito sobre Categoria, selecionaremos a opção "Show Context Actions" e criaremos um enum chamado "Categoria" (Create enum 'Categoria').

No novo arquivo criado (Categoria.java), declararemos os gêneros que conhecemos. Declaramos estes gêneros em letras maiúsculas, porque normalmente associamos constantes a estes termos.

Dito isso, teremos os gêneros ACAO, ROMANCE, COMEDIA, DRAMA, e CRIME.

Categoria.java:

package br.com.alura.screenmatch.model;

public enum Categoria {
    ACAO,
    ROMANCE,
    COMEDIA,
    DRAMA,
    CRIME;
}

Jacqueline: Por enquanto, podemos deixá-los assim. Se necessário, podemos inserir outros gêneros. Basicamente, queremos limitar as categorias, de modo que estejam restritas a estes tipos específicos. Esta é a nossa ideia central: limitá-las a uma constante.

Iasmin: Existem algumas diferenças a serem consideradas. Por exemplo: digitamos "ACAO" e "COMEDIA", mas se recebermos esses rótulos no terminal, notaremos que se tratam de "Action" e "Comedy", por exemplo.

Embora alguns gêneros apresentem a mesma denominação em inglês e em português, nem todos seguem esse padrão. Portanto, necessitaremos de uma correspondência entre essas nomenclaturas. No enum, essa correspondência é feita adicionando um novo atributo.

Após o gênero CRIME, vamos declarar um novo atributo que será a categoria do OMDB. Em seguida, veremos como isso será aplicado. Este atributo será uma string privada (private String) chamada categoriaOmdb. Essa categoria deverá ser passada para cada constante.

Assim, para ACAO, o correspondente seria Action. Para ROMANCE, repetimos a palavra, já que o termo é igual em inglês. Da mesma forma, temos Comedy correspondendo a COMEDIA, Drama para DRAMA, e Crime para CRIME.

public enum Categoria {
    ACAO("Action"),
    ROMANCE("Romance"),
    COMEDIA("Comedy"),
    DRAMA("Drama"),
    CRIME("Crime");
    
    private String categoriaOmdb;
}

Feito isso, teremos um construtor que será responsável por adicionar essa categoriaOmdb ao que está no enum. Na linha 12, podemos declarar o construtor chamado Categoria que receberá uma String chamada categoriaOmdb.

Ao completar, podemos perceber que o IntelliJ já nos mostra o que é feito, pois ele identifica o atributo ao instanciá-lo.

Em seguida, fazemos como um construtor normal. A categoriaOmdb, ou seja, this.categoriaOmdb, recebe a string categoriaOmdb. Assim, temos um enum de categorias.

public enum Categoria {
    ACAO("Action"),
    ROMANCE("Romance"),
    COMEDIA("Comedy"),
    DRAMA("Drama"),
    CRIME("Crime");
    
    private String categoriaOmdb;
    
    Categoria(String categoriaOmdb){
        this.categoriaOmdb = categoriaOmdb;
    }
}

Modificações na classe Serie

Podemos voltar para a classe Serie e começar a modificar os dados recebidos. Primeiramente, criaremos um construtor. Da mesma forma que a classe Episodio recebe DadosEpisodio, agora a classe Serie receberá um objeto DadosSerie.

Jacqueline: Exatamente, iniciaremos a associação e transformação de valores, pois em DadosSerie, tudo vem em String, e agora já sabemos haver alguns valores que queremos tratar de forma diferente, como avaliacao e genero.

Iasmin: Então, após a declaração dos atributos, na linha de código 14, vamos criar um construtor public chamado Serie(), recebendo DadosSerie.

Serie.java:

public Serie(DadosSerie dadosSerie){

}

Feito isso, começaremos a fazer as atribuições.

O campo this.titulo receberá o correspondente no objeto dadosSerie, ou seja, dadosSerie.titulo(). Todos os campos que são strings podem ser atribuídos diretamente.

Da mesma forma, o campo totalTemporadas será atribuído com o valor correspondente da classe dadosSerie, então dadosSerie.totalTemporadas(). No campo avaliacao, haverá uma mudança. A avaliacao era uma String, mas precisará ser transformada em Double.

Na classe Episodio, usamos o try…catch para fazer essa conversão, em que se algo desse errado na conversão, o valor era transformado em 0.0. Agora, nessa classe, faremos a mesma coisa, mas utilizando a estrutura Optional, que já conhecemos.

O processo agora será utilizar a classe OptionalDouble, chamar o método of() dela, e passar um valor Double. Faremos isso com a parte onde tentamos ler o valor da avaliação. Portanto, faremos um Double.valueOf(dadosSerie.avaliacao()). No entanto, isso pode falhar, sendo necessário inserir algum outro valor. Agora entra a outra parte do Optional.

Após fazer isto, precisaremos chamar um orElse(), onde podemos passar o zero. Feito isto, temos uma estrutura bastante semelhante ao que tínhamos no try-catch, mas de forma diferente.

public Serie(DadosSerie dadosSerie){
    this.titulo = dadosSerie.titulo();
    this.totalTemporadas = dadosSerie.totalTemporadas();
    this.avaliacao = OptionalDouble.of(Double.valueOf(dadosSerie.avaliacao())).orElse(0);
}

Jacqueline: Temos quase um if…else melhorado. Tentamos obter o valor Double. Caso isso não aconteça, atribuímos 0 para a avaliação. Essa é uma maneira de estipularmos um valor padrão, caso ocorra qualquer erro e não consigamos obter o valor da avaliação.

Modificações na classe Categoria

Iasmin: Para Categoria, também serão necessárias algumas alterações.

Se usarmos this.genero e, em seguida, chamarmos a categoria, o que seria a maneira normal de lidarmos com o enum, poderíamos até atribuir algo à série. Porém, o que queremos é sempre ter dados dinâmicos vindos de nossa API, do OMDB, e convertidos na nossa série.

Para isso, precisaremos de um método auxiliar no enum que fará essa conversão para nós. Apresentaremos esse método e vamos copiá-lo e colá-lo no enum, após o construtor.

Categoria.java:

public static Categoria fromString(String text) {
    for (Categoria categoria : Categoria.values()) {
        if (categoria.categoriaOmdb.equalsIgnoreCase(text)) {
            return categoria;
        }
    }
    throw new IllegalArgumentException("Nenhuma categoria encontrada para a string fornecida: " + text);
}

Jacqueline: O funcionamento é simples: se o OMDB retornar a palavra "Action", consideramos isso como ACAO; se retornar "Comedy", consideramos isso como COMEDIA.

Ou seja, esse método vai interpretar dinamicamente o valor textual vindo do OMDB e irá converter na nossa categoria de enum, correto?

Iasmin: Exatamente. Podemos observar que se trata de um método estático que percorrerá nossa lista de constantes e, para cada uma delas, se o texto correspondente for igual à categoria do OMDB, ele associará à nossa categoria.

Finalizando as atribuições

Agora, em Serie.java, chamaremos esse método. Em vez de instanciar uma categoria, como nós temos um método estático, podemos usar Categoria.fromString() e passar o texto que vem de dadosSerie. Assim, faremos dadosSerie.genero() e com isso teremos a correspondência.

Serie.java:

public Serie(DadosSerie dadosSerie){
    this.titulo = dadosSerie.titulo();
    this.totalTemporadas = dadosSerie.totalTemporadas();
    this.avaliacao = OptionalDouble.of(Double.valueOf(dadosSerie.avaliacao())).orElse(0);
    this.genero = Categoria.fromString(dadosSerie.genero());
}

Para as outras strings, só precisamos fazer a atribuição básica.

Jacqueline: No entanto, ao observarmos o gênero no terminal, percebemos que são retornadas três palavras, como, por exemplo, "Action, Crime, Romance". Se quisermos pegar apenas a primeira palavra, o que podemos fazer? Afinal, não queremos usar a string inteira para tentar achar a correspondência, pois isso dará errado.

Iasmin: Verdade, temos que pegar o primeiro gênero antes da vírgula. Para isso, podemos usar o método split() para separar as palavras que estão divididas por vírgula.

O método split() vai separar uma string grande, contendo todos os gêneros, e um array de strings, então em vez de termos "Drama, Romance, Comédia", teremos palavras separadas e pegaremos apenas a primeira, representada pelo 0 entre colchetes.

Porém, como isso pode ter alguns espaços em branco ou coisas que não queremos que sejam diferentes da palavra em si, nós também devemos usar o método trim(), que vai remover caracteres em branco, como espaços e quebras de linha.

public Serie(DadosSerie dadosSerie){
    this.titulo = dadosSerie.titulo();
    this.totalTemporadas = dadosSerie.totalTemporadas();
    this.avaliacao = OptionalDouble.of(Double.valueOf(dadosSerie.avaliacao())).orElse(0);
    this.genero = Categoria.fromString(dadosSerie.genero().split(",")[0].trim());
}

Agora está correto, não é, Jacque?

Jacqueline: Sim, vamos pegar apenas o primeiro item que vier do OMDB como categoria.

Iasmin: Para as outras strings, faremos atribuições simples e rápidas.

Jacqueline: Ainda falta atores, poster e sinopse.

Iasmin: this.atores receberá dadosSerie.atores(). A própria IDE nos auxiliará nessa atribuição. Na sequência, this.poster receberá dadosSerie.poster(); e, por fim, this.sinopse receberá dadosSeries.sinopse().

public Serie(DadosSerie dadosSerie){
    this.titulo = dadosSerie.titulo();
    this.totalTemporadas = dadosSerie.totalTemporadas();
    this.avaliacao = OptionalDouble.of(Double.valueOf(dadosSerie.avaliacao())).orElse(0);
    this.genero = Categoria.fromString(dadosSerie.genero().split(",")[0].trim());
    this.atores = dadosSerie.atores();
    this.poster = dadosSerie.poster();
    this.sinopse = ConsultaChatGPT.obterTraducao(dadosSerie.sinopse()).trim();
}

Conclusão

Fechamos o nosso construtor, correto, Jacque?

Jacqueline: Sim, nosso construtor já contempla tudo. O que vier de dadosSerie, nós conseguiremos transformar efetivamente em uma série. Na sequência, podemos começar a testar, fazer os getters e setters, o toString(), e o que mais for necessário nessa classe.

Iasmin: Vamos tomar nosso café, pois fizemos bastante coisa!

Jacqueline: Até daqui a pouco!

Sobre o curso Java: persistência de dados e consultas com Spring Data JPA

O curso Java: persistência de dados e consultas com Spring Data JPA possui 333 minutos de vídeos, em um total de 74 atividades. Gostou? Conheça nossos outros cursos de Java 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 Java acessando integralmente esse e outros cursos, comece hoje!

Plus

De
R$ 1.800
12X
R$109
à vista R$1.308
  • Acesso a TODOS os cursos da Alura

    Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

Matricule-se

Pro

De
R$ 2.400
12X
R$149
à vista R$1.788
  • Acesso a TODOS os cursos da Alura

    Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

  • Luri, a inteligência artificial da Alura

    Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com Luri até 100 mensagens por semana.

  • Alura Língua (incluindo curso Inglês para Devs)

    Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.

Matricule-se
Conheça os Planos para Empresas

Acesso completo
durante 1 ano

Estude 24h/dia
onde e quando quiser

Novos cursos
todas as semanas