Programação para Web 3

Cadastro de Informações

Prof. Me. Danilo Bueno

Relembrando

O que foi feito na aula anterior?

  • O repositório passou a consultar o banco com o JdbcTemplate
  • queryForList trouxe as linhas, e deMap converteu cada uma em objeto
  • O controller e a view exibem esses dados na tela

A aplicação já lê do banco. Falta escrever nele.

Como os dados entram hoje?

Todos os registros do banco chegaram lá por uma destas vias:

  • Uma migração escrita pelo desenvolvedor
  • Um comando digitado direto no terminal do MySQL

Quem usa o sistema consegue cadastrar alguma coisa?

Cadastrando um registro

Como levar um dado da tela até o banco de dados?

Quatro etapas:

  1. Exibir o formulário
  2. Receber e validar os dados
  3. Executar o comando de inserção
  4. Redirecionar o usuário

1. Exibindo o formulário

Uma rota apenas devolve o template, sem nenhum dado:

@GetMapping("/produtos/novo")public String formulario() {    return "produto-novo";}
<form method="post" action="/produtos">    <input type="text" name="nome" value="${nome!}">    <input type="text" name="preco" value="${preco!}">    <button type="submit">Cadastrar</button></form>

Explicando o código

Formulário e rota

  • @GetMapping("/produtos/novo"): a rota que exibe o formulário
  • action="/produtos": para onde o formulário será enviado
  • name="nome": o nome do campo, que o controller usará para recebê-lo
  • ${nome!}: mantém o valor digitado caso a página seja reexibida

São duas rotas diferentes: uma exibe o formulário, outra recebe o envio.

2. Recebendo e validando

O método de POST recebe os campos e verifica se estão preenchidos:

@PostMapping("/produtos")public String cadastrar(Model model,        @RequestParam String nome, @RequestParam double preco) {    if (nome.isBlank()) {        model.addAttribute("erro", "Informe o nome do produto.");        model.addAttribute("preco", preco);        return "produto-novo";    }    ...}

Por que validar antes de gravar?

  • Um dado inválido gravado no banco permanece lá
  • Corrigi-lo depois exige acesso ao próprio banco de dados
  • A validação é a última barreira antes do dado se tornar permanente

Em caso de erro, o formulário é reexibido com a mensagem e os valores já digitados.

3. Executando a inserção

Nem toda instrução SQL devolve dados:

Tipo Instrução SQL Devolve
Consulta SELECT As linhas encontradas
Comando INSERT, UPDATE, DELETE Linhas afetadas

Por isso o JdbcTemplate separa os dois casos em métodos diferentes.

O método update

Para comandos que alteram dados, o método é o update:

public void salvar(Produto produto) {    String sql = "INSERT INTO produtos (nome, preco) VALUES (?, ?)";    jdbcTemplate.update(sql, produto.getNome(), produto.getPreco());}

Explicando o código

Método salvar

  • INSERT INTO produtos (nome, preco): as colunas que serão preenchidas
  • VALUES (?, ?): um marcador para cada coluna informada
  • update(sql, nome, preco): os valores preenchem os ? na ordem

O nome update vale para qualquer comando que altera dados, não apenas para o SQL UPDATE.

E a coluna id?

O INSERT não informa o id do novo registro:

INSERT INTO produtos (nome, preco) VALUES (?, ?);
  • A coluna foi criada como AUTO_INCREMENT na migração
  • O próprio banco atribui o valor a cada nova linha

Cabe ao banco garantir que dois registros nunca recebam o mesmo identificador.

4. Redirecionando o usuário

Gravado o registro, o usuário é levado para a listagem:

Produto produto = new Produto();produto.setNome(nome);produto.setPreco(preco);produtoRepository.salvar(produto);return "redirect:/produtos";

Sem o redirecionamento, um F5 reenviaria o POST e cadastraria o produto novamente.

Juntando tudo

O método de cadastro completo

@PostMapping("/produtos")public String cadastrar(Model model,        @RequestParam String nome, @RequestParam double preco) {    if (nome.isBlank()) {        model.addAttribute("erro", "Informe o nome do produto.");        model.addAttribute("preco", preco);        return "produto-novo";    }    Produto produto = new Produto();    produto.setNome(nome);    produto.setPreco(preco);    produtoRepository.salvar(produto);    return "redirect:/produtos";}

Explicando o código

Método cadastrar

  • Recebe os campos do formulário com @RequestParam
  • Valida: se houver erro, devolve o formulário com a mensagem
  • Monta o objeto Produto a partir dos dados recebidos
  • Chama o repositório, que executa o INSERT
  • Redireciona para a listagem, onde o novo registro aparece

O repositório completo

@Repositorypublic class ProdutoRepository {    @Autowired    private JdbcTemplate jdbcTemplate;    public List<Produto> findAll() { ... }    public void salvar(Produto produto) {        String sql = "INSERT INTO produtos (nome, preco) VALUES (?, ?)";        jdbcTemplate.update(sql, produto.getNome(), produto.getPreco());    }}

A mesma classe agora lê e escreve no banco.

O caminho de um cadastro

[ Formulário ]     usuário preenche e envia
       ▼
[ Controller ]     @RequestParam + validação
       ▼
[ Repositório ]    jdbcTemplate.update()
       ▼
[ Banco ]          INSERT, a linha passa a existir
       ▼
[ Redirect ]       listagem exibe o novo registro

Obrigado!

Prof. Me. Danilo Bueno
[email protected]