# O que estudar antes de Spring Boot: Java, HTTP e SQL na prática

Veja o que estudar de Java, HTTP e SQL antes de Spring Boot, com tarefas de diagnóstico e um projeto incremental para decidir quando avançar.

Por Bruno Rana

Publicado em: 2026-10-22
Atualizado em: 2026-11-04

Artigo original: https://buildrun.com.br/blog/o-que-estudar-antes-spring-boot/

![Uma lupa seleciona no catálogo os livros 11 e 13 com estado EM_LEITURA.](https://buildrun.com.br/diagrams/spring-book-filter-flow.webp)

Comece com resultado esperado: livros 11 e 13, sem mutação do catálogo.

É fácil adiar o primeiro projeto com Spring Boot por achar que ainda falta estudar Java inteiro. Também é possível avançar tão cedo que cada anotação parece funcionar por um motivo que você ainda não consegue explicar. Para decidir seu próximo passo, você precisa localizar o que já entende no código e o que ainda depende de copiar uma solução.

Comece pela capacidade de acompanhar uma regra pequena: quais dados ela recebe, que decisões toma e qual resultado devolve. HTTP e SQL entram quando essa regra precisa atender requisições e guardar informações. Você não precisa dominar todos esses assuntos de uma vez.

O percurso abaixo ajuda a identificar essas lacunas pela prática. Se uma etapa travar, você terá um assunto específico para revisar e poderá retomar o trabalho de onde parou.

## 1. Entenda a consulta antes de adicionar o framework

Uma consulta simples permite observar essa base sem configurar um servidor. Vamos selecionar livros pelo status de leitura e, depois, combinar esse critério com o autor. O mesmo catálogo acompanhará o percurso da coleção em memória até as decisões de API e banco.

Use estes dados fictícios:

| ID | Livro | Autor | Status |
| --- | --- | --- | --- |
| 11 | Jardim de inverno | Ana | `EM_LEITURA` |
| 12 | Caminhos da cidade | Ana | `CONCLUIDO` |
| 13 | Uma tarde no parque | Rui | `EM_LEITURA` |

A primeira tarefa é selecionar os livros em leitura. Antes de escrever o método, anote os IDs esperados: 11 e 13. Selecionar deve produzir um resultado sem alterar os livros de origem.

Esse recorte já ajuda a localizar o que estudar:

| Se você não consegue… | Revise… |
| --- | --- |
| Explicar o valor recebido e o resultado devolvido | Tipos, argumentos, variáveis locais e retorno de métodos. |
| Representar livros diferentes | Objetos, instâncias e referências. |
| Percorrer os livros e selecionar alguns | Coleções e condições. |
| Distinguir busca sem resultado de entrada inválida | Validação e tratamento de erros. |
| Conferir os IDs sem olhar apenas a tela | Testes e resultados esperados. |
| Executar fora da IDE | JDK, ferramenta de build, dependências e instruções de execução. |

Estude a lacuna que aparecer e retome a consulta. O [índice oficial de aprendizado Java](https://dev.java/learn/) reúne essas referências; não é necessário concluir cada assunto listado ali para continuar o projeto.

## 2. Combine os filtros mantendo uma regra clara

Agora a consulta aceita autor, status ou os dois. Quando ambos estiverem presentes, cada livro precisa atender às duas condições. Sem filtros, retornamos todos os livros deste pequeno catálogo.

<figure class="explainer explainer--sketch">
<img src="https://buildrun.com.br/diagrams/spring-optional-filter-semantics.webp" srcset="https://buildrun.com.br/diagrams/spring-optional-filter-semantics-420.webp 420w, https://buildrun.com.br/diagrams/spring-optional-filter-semantics-840.webp 840w, https://buildrun.com.br/diagrams/spring-optional-filter-semantics.webp 1254w" sizes="(max-width: 800px) calc(100vw - 32px), 760px" width="1254" height="1254" loading="lazy" decoding="async" alt="Filtros se combinam numa caixa; bandejas distintas representam ausência de filtro, resultado vazio e entrada inválida.">
<figcaption>Ausência de filtro, entrada inválida e busca sem correspondência têm resultados distintos.</figcaption>
</figure>

| Consulta | IDs esperados |
| --- | --- |
| Status `EM_LEITURA` | 11 e 13 |
| Autor Ana | 11 e 12 |
| Autor Ana e status `EM_LEITURA` | 11 |
| Autor Lia | Nenhum |
| Nenhum filtro | 11, 12 e 13 |

Neste exercício, `null` representa um filtro ausente. A comparação de autor é exata, incluindo maiúsculas e acentos. Um nome vazio não equivale a filtro ausente: é uma entrada que vamos recusar. Essa decisão precisa permanecer consistente quando a consulta chegar por HTTP.

O código abaixo implementa esse contrato sem Spring. Salve como `CatalogoDemo.java` e execute `java CatalogoDemo.java` com Java 21:

```java
import java.util.ArrayList;
import java.util.List;

public class CatalogoDemo {
    enum Status { NAO_INICIADO, EM_LEITURA, CONCLUIDO }
    record Livro(int id, String autor, Status status) {}

    static List<Integer> filtrar(List<Livro> livros, String autor,
                                 Status status) {
        if (autor != null && autor.isBlank()) {
            throw new IllegalArgumentException("Autor vazio");
        }
        List<Integer> ids = new ArrayList<>();
        for (Livro livro : livros) {
            boolean atendeAutor = autor == null
                || livro.autor().equals(autor);
            boolean atendeStatus = status == null
                || livro.status() == status;
            if (atendeAutor && atendeStatus) ids.add(livro.id());
        }
        return ids;
    }

    static void conferir(List<Integer> atual, Integer... esperado) {
        if (!atual.equals(List.of(esperado))) {
            throw new AssertionError("Resultado inesperado: " + atual);
        }
    }

    public static void main(String[] args) {
        var livros = List.of(
            new Livro(11, "Ana", Status.EM_LEITURA),
            new Livro(12, "Ana", Status.CONCLUIDO),
            new Livro(13, "Rui", Status.EM_LEITURA)
        );
        conferir(filtrar(livros, null, Status.EM_LEITURA), 11, 13);
        conferir(filtrar(livros, "Ana", null), 11, 12);
        conferir(filtrar(livros, "Ana", Status.EM_LEITURA), 11);
        conferir(filtrar(livros, "Lia", null));
        conferir(filtrar(livros, null, null), 11, 12, 13);
        conferir(filtrar(List.of(), null, null));
        conferir(filtrar(livros, null, Status.CONCLUIDO), 12);
        boolean recusou = false;
        try { filtrar(livros, " ", null); }
        catch (IllegalArgumentException erro) { recusou = true; }
        if (!recusou) throw new AssertionError("Autor vazio aceito");
        System.out.println("Consultas verificadas");
    }
}
```

O `record` agrupa os dados de cada livro. A lista guarda os registros; o `for` percorre um livro de cada vez. `||` permite atender a um filtro ausente, enquanto `&&` exige atender aos dois critérios. A lista de saída guarda apenas os identificadores selecionados e mantém a ordem de entrada neste programa.

A diferença entre unir resultados e combinar condições aparece no caso de Ana em leitura: a resposta contém apenas 11. Se viessem 11, 12 e 13, a consulta estaria aceitando quem atende a qualquer um dos filtros, em vez de exigir ambos.

## 3. Receba a mesma consulta por HTTP

Só agora acrescente Spring Boot. Um *controller* é a parte que recebe a requisição e encaminha a operação. Antes de escrevê-lo, defina como o cliente enviará os filtros e reconhecerá o resultado.

<figure class="explainer explainer--sketch">
<img src="https://buildrun.com.br/diagrams/spring-http-request-flow.webp" srcset="https://buildrun.com.br/diagrams/spring-http-request-flow-420.webp 420w, https://buildrun.com.br/diagrams/spring-http-request-flow-840.webp 840w, https://buildrun.com.br/diagrams/spring-http-request-flow.webp 1254w" sizes="(max-width: 800px) calc(100vw - 32px), 760px" width="1254" height="1254" loading="lazy" decoding="async" alt="Uma bibliotecária distingue consulta válida sem resultado, livro inexistente e pedido inválido, com respostas 200, 404 e 400.">
<figcaption>Lista vazia significa consulta válida sem correspondência; ID 99 inexistente retorna 404.</figcaption>
</figure>

| Requisição | Contrato do exercício |
| --- | --- |
| `GET /livros?status=EM_LEITURA` | 200, com os livros 11 e 13. |
| `GET /livros?autor=Ana&status=EM_LEITURA` | 200, com o livro 11. |
| `GET /livros` | 200, com todos os livros. |
| `GET /livros?autor=Lia` | 200, com lista vazia. |
| `GET /livros?status=INVENTADO` | 400, com mensagem de entrada inválida. |
| `GET /livros?autor=` | 400, com mensagem de autor vazio. |
| `GET /livros/99` | 404, pois esse identificador não existe. |

Esses são os códigos HTTP escolhidos para o exercício. A implementação precisa distinguir parâmetro ausente de valor inválido: um status desconhecido não deve virar `null` e acabar removendo o filtro silenciosamente.

Acompanhe o caminho completo: parâmetro textual recebido, conversão para `Status`, validação, consulta e resposta. O programa anterior recebe um `Status` já convertido; ainda não implementa a leitura de HTTP nem a busca por identificador.

O [guia oficial de serviço REST do Spring](https://spring.io/guides/gs/rest-service/) apresenta requisição GET, parâmetros e resposta JSON. Ao adaptar esse mecanismo ao catálogo, explique o papel das anotações usadas. Se o resultado vier errado, descubra se o parâmetro chegou incorretamente ou se a seleção falhou antes de culpar o framework.

## 4. Guarde os livros e repita as verificações

Em um banco local de treino, crie uma tabela para os livros e insira o mesmo conjunto de dados. Execute consultas por status, por autor e pelos dois critérios. Compare os IDs com a tabela anterior.

Pratique também atualizar um único livro pelo identificador e consultar o resultado. Confira a condição antes de executar uma atualização: um filtro errado pode atingir outros registros. O [tutorial SQL do PostgreSQL](https://www.postgresql.org/docs/current/tutorial-sql.html) cobre criação, inserção, consulta e atualização.

Depois substitua o armazenamento em memória pelo banco. Se usar mapeamento objeto-relacional, camada que relaciona objetos a tabelas, continue conferindo o que foi gravado e consultado. Reinicie a aplicação e repita a busca: os dados devem continuar disponíveis, sem depender da coleção criada no início do programa.

Defina a ordenação da consulta antes de comparar listas pela posição. O código em memória mantém a ordem de entrada; o banco precisa de uma ordenação explícita quando essa ordem fizer parte do contrato.

Desligue apenas o banco de treino para observar uma falha controlada. Diferencie consulta executada sem correspondências de consulta que nem pôde ser realizada. A resposta ao cliente deve comunicar a falha sem expor detalhes internos ou credenciais.

Se o projeto passar a atualizar o livro e registrar um histórico na mesma operação, estude [transações](https://www.postgresql.org/docs/current/tutorial-transactions.html) para tratar as gravações em conjunto. Faça esse incremento depois de compreender a gravação simples.

## Como decidir se já pode avançar

Você pode seguir para a próxima etapa quando consegue explicar a entrada, a regra e a saída da atual; reproduzir um resultado esperado; e investigar uma divergência concreta. Consultar documentação faz parte desse processo.

Se houver falha, separe ambiente de comportamento: uma versão incompatível de Java exige outra investigação que um filtro incorreto. Leia a mensagem e a *stack trace*, sequência de chamadas associada à exceção, procurando onde seu código participou.

Ao parar, deixe uma anotação específica: qual consulta funciona, qual falhou, quais IDs esperava e o que vai verificar. Isso permite retomar o mesmo projeto em vez de reiniciar toda a sequência de aulas.

O catálogo ainda não é uma aplicação pronta para produção. Acesso, concorrência, volume de dados e operação exigem decisões adicionais. Para conectar essas responsabilidades, veja a [visão de Java, Spring Boot e DevOps](https://buildrun.com.br/blog/trilhas-de-estudo/). Se usar IA durante o roteiro, acompanhe o [ciclo de estudo sem pular fundamentos](https://buildrun.com.br/blog/java-junior-ia-sem-pular-fundamentos/).

As referências oficiais foram consultadas em 22/10/2026. Registre as versões do seu projeto. Se preferir estudar com a Build & Run, consulte os [conteúdos da formação](https://buildrun.com.br/blog/formacao-buildrun/) a partir da lacuna que identificou neste percurso.
