quinta-feira, 22 de setembro de 2016

CRUD com REST Spring-Boot e JPA


A meta de hoje é demonstrar um CRUD no Spring-boot. O Spring-boot é uma evolução do Spring e possui diversos pacotes de implementação incluindo JPA que faz parte da persistência do objeto relacional. No JPA os objetos da camada de modelo de banco de dados são tratados com o nome de Entities ou Entity.

Vamos inciar abrindo o Eclipse com suporte a Java, levando em consideração o JDK e Jre já instalados assim como as variáveis de ambiente.

Na caixa input de acesso rápido digite marketplace e deverá abrir uma janela.

Na caixa de entrada de texto digite STS e clique GO. Deverá aparecer um plugin String Tool Suite que vai nos ajudar a implementar o Spring-boot no Eclipse.






No meu caso o STS já está instalado. Se não estiver clique em Install e proceda com a instalação. O Eclipse deverá ser reiniciado ao término.


Com o Eclipse aberto novamente vamos clicar em File>>New>>Other e selecionar dentro da pasta Spring um projeto do tipo Spring Starter Project e clicar em next.





Deverá abri a janela abaixo:





Clique em next e na próxima janela selecione o projeto web:




Na janela seguinte clique em finish.


O projeto será criado. Na estrutura de arquivos deverá aparecer o seguinte:





O arquivo pom.xml é a alma do Maven. Através dele faremos a importação das libs necessárias. Para isso, serão adicionadas algumas dependências e o arquivo deverá ficar com o seguinte aspecto:


  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://mvnrepository.com/artifact/mysql/mysql-connector-java http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.     <modelVersion>4.0.0</modelVersion>
  5.     <groupId>com.example</groupId>
  6.     <artifactId>demo</artifactId>
  7.     <version>0.0.1-SNAPSHOT</version>
  8.     <packaging>jar</packaging>
  9.     <name>demo</name>
  10.     <description>Demo project for Spring Boot</description>
  11.     <parent>
  12.         <groupId>org.springframework.boot</groupId>
  13.         <artifactId>spring-boot-starter-parent</artifactId>
  14.         <version>1.4.1.RELEASE</version>
  15.         <relativePath /> <!-- lookup parent from repository -->
  16.     </parent>
  17.     <properties>
  18.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  19.         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  20.         <java.version>1.8</java.version>
  21.     </properties>
  22.     <dependencies>
  23.         <dependency>
  24.             <groupId>org.springframework.boot</groupId>
  25.             <artifactId>spring-boot-starter-jersey</artifactId>
  26.         </dependency>
  27.         <dependency>
  28.             <groupId>org.springframework.boot</groupId>
  29.             <artifactId>spring-boot-starter-web</artifactId>
  30.         </dependency>
  31.         <dependency>
  32.             <groupId>org.springframework.boot</groupId>
  33.             <artifactId>spring-boot-starter-web-services</artifactId>
  34.         </dependency>
  35.         <dependency>
  36.             <groupId>org.springframework.boot</groupId>
  37.             <artifactId>spring-boot-starter-test</artifactId>
  38.             <scope>test</scope>
  39.         </dependency>
  40.         <dependency>
  41.             <groupId>org.springframework.boot</groupId>
  42.             <artifactId>spring-boot-starter-data-jpa</artifactId>
  43.         </dependency>
  44.         <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  45.         <dependency>
  46.             <groupId>mysql</groupId>
  47.             <artifactId>mysql-connector-java</artifactId>
  48.             <version>5.1.6</version>
  49.         </dependency>
  50.     </dependencies>
  51.     <build>
  52.         <plugins>
  53.             <plugin>
  54.                 <groupId>org.springframework.boot</groupId>
  55.                 <artifactId>spring-boot-maven-plugin</artifactId>
  56.             </plugin>
  57.         </plugins>
  58.     </build>
  59. </project>




Feito isso, clique com o direito sobre o projeto acesse Maven>>Update Project.

Veja a classe DemonstraAplication.java dentro do pacote exemplo.com.




Esta classe implementa uma chamada básica com o seguinte conteúdo:


  1. package com.example;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class DemoApplication {
  6.     public static void main(String[] args) {
  7.         SpringApplication.run(DemoApplication.class, args);
  8.     }
  9. }



Vamos criar uma classe ClienteController.java dentro de um novo pacote com o nome com.example.controller com o seguinte conteúdo:

  1. package com.example.controller;
  2. import java.util.Collection;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.http.HttpStatus;
  5. import org.springframework.http.MediaType;
  6. import org.springframework.http.ResponseEntity;
  7. import org.springframework.web.bind.annotation.PathVariable;
  8. import org.springframework.web.bind.annotation.RequestBody;
  9. import org.springframework.web.bind.annotation.RequestMapping;
  10. import org.springframework.web.bind.annotation.RequestMethod;
  11. import org.springframework.web.bind.annotation.RestController;
  12. import com.example.model.Cliente;
  13. import com.example.service.ClienteService;
  14. @RestController
  15. public class ClienteController {
  16.    
  17.     @Autowired
  18.     ClienteService clienteService;
  19.    
  20.     @RequestMapping(method=RequestMethod.POST, value="/clientes", consumes=MediaType.APPLICATION_JSON_VALUE)
  21.     public ResponseEntity<Cliente> cadastrarCliente(@RequestBody Cliente cliente){
  22.         Cliente clienteCadastrado = clienteService.cadastrar(cliente);
  23.         return new ResponseEntity<Cliente>(clienteCadastrado, HttpStatus.CREATED);
  24.     }
  25.    
  26.     @RequestMapping(method=RequestMethod.GET, value="/clientes", produces=MediaType.APPLICATION_JSON_VALUE)
  27.     public ResponseEntity<Collection<Cliente>> buscarTodosClientes(){
  28.         Collection<Cliente> clientesBuscados = clienteService.buscarTodos();
  29.         return new ResponseEntity<>(clientesBuscados, HttpStatus.OK);
  30.     }
  31.     @RequestMapping(method=RequestMethod.DELETE, value="/clientes/{id}")
  32.     public ResponseEntity<Cliente> excluirCliente(@PathVariable Integer id){
  33.         Cliente clienteEncontrado = clienteService.buscarPorId(id);
  34.         if(clienteEncontrado==null){
  35.             return new ResponseEntity<>(HttpStatus.NOT_FOUND);
  36.         }
  37.         clienteService.excluir(clienteEncontrado);
  38.         return new ResponseEntity<Cliente>(HttpStatus.OK);
  39.     }
  40.     @RequestMapping(method=RequestMethod.PUT, value="/clientes", consumes=MediaType.APPLICATION_JSON_VALUE)
  41.     public ResponseEntity<Cliente> alterarCliente(@RequestBody Cliente cliente){
  42.         Cliente clienteAlterado = clienteService.alterar(cliente);
  43.         return new ResponseEntity<Cliente>(clienteAlterado, HttpStatus.OK);
  44.     }
  45.    
  46. }

Vamos criar um pacote com.example.service com a classe ClienteService.java com o seguinte conteúdo:

  1. package com.example.service;
  2. import java.util.Collection;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. import com.example.model.Cliente;
  8. import com.example.repository.ClienteRepository;
  9. @Service
  10. public class ClienteService {
  11.     @Autowired
  12.     ClienteRepository clienteRepository;
  13.    
  14.    
  15.     public Cliente cadastrar(Cliente cliente){
  16.         return clienteRepository.save(cliente);
  17.     }
  18.    
  19.     public Collection<Cliente> buscarTodos(){
  20.         return clienteRepository.findAll();
  21.     }

  22.     public void excluir(Cliente cliente){
  23.         clienteRepository.delete(cliente);
  24.     }

  25.     public Cliente buscarPorId(Integer id) {
  26.         return clienteRepository.findOne(id);
  27.     }

  28.     public Cliente alterar(Cliente cliente){
  29.         return clienteRepository.save(cliente);
  30.     }
  31. }


Vamos criar o pacote com.example.model com o objeto Cliente.java com o seguinte conteúdo.

  1. package com.example.model;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.Id;
  5. @Entity
  6. public class Cliente {
  7.     @Id
  8.     @GeneratedValue
  9.     private Integer id;
  10.     private String nome;
  11.     public Integer getId() {
  12.         return id;
  13.     }
  14.     public void setId(Integer id) {
  15.         this.id = id;
  16.     }
  17.     public String getNome() {
  18.         return nome;
  19.     }
  20.     public void setNome(String nome) {
  21.         this.nome = nome;
  22.     }
  23.    
  24. }

Repare a @nnotation @Entity, é ela que define a classe como objeto e permite o acesso do service. Dentro do banco de dados a tabela precisa ter o mesmo nome da classe e as variáveis private precisam ter o mesmo nome que as colunas do banco de dados. Essa é a regra.

Vamos criar o arquivo ClienteRepository.java dentro do pacote com.example.repository com o seguinte conteúdo:

  1. package com.example.repository;
  2. import org.springframework.data.jpa.repository.JpaRepository;
  3. import org.springframework.stereotype.Repository;
  4. import com.example.model.Cliente;
  5. @Repository
  6. public interface ClienteRepository extends JpaRepository<Cliente, Integer>{
  7. }

Agora vamos configurar o arquivo application.properties com os dados de acesso ao BD com o nome da database, usuário e senha:


  1. server.port=${port:8081}
  2. spring.datasource.url= jdbc:mysql://localhost:3306/db_cli
  3. spring.datasource.username=root
  4. spring.datasource.password=root123
  5. spring.jpa.hibernate.ddl-auto=create-drop


Se o BD ainda não foi criado ainda, crie conforme o modelo Entity, com os mesmos nomes conforme já descrito.

Feito isso, todos os erros do projeto deverão desaparecer.

A estrutura deverá ficar da seguinte forma:




O sistema de arquivos já pode ser executado. Clique com o direito sobre o projeto em Run as>>Spring Boot App. A página poderá ser testada utilizando o Plugin do Chrome Postman. Depois de testar o projeto pode parar o servidor e vamos fazer uma alteração para entender um pouco o Hibernate. O Hibernate é nativo do Spring-boot.

Vamos alterar o arquivo ClienteRepository que na verdade é uma interface. Troque "public interface ClienteRepository" por "public class ClienteRepository" e salve o arquivo.

O Eclipse deverá mostrar um erro sublinhado em JpaRepository. Clique com o direito sobre a palavra para corrigir e escolha a opção "change extends to implements".

O Eclipse deverá mostrar um novo erro na palavra ClienteRepository. Clique com o direito sobre a palavra para corrigir e escolha a opção "add unimplemented methods".

A classe deverá exibir todos os métodos nativos do Hibernate que podem ser invocados pelo service, como: save(), delete(), listAll(), findOne(), getOne(), ...


Repare que em nenhum momento foram utilizados Beans. Essa implementação deverá se repetir para todas as tabelas do sistema. Este é um formato de implementação de Spring muito tradicional. O processo é muito simples e sistêmico. Isso é Java!!

Ainda existe a possibilidade de várias outras formas de implementação se for necessário, mas essa é uma das melhores. Um formato MVC de requisição com uma variante de interfaces em todas as camadas e um Dao herdado, utilizei de forma similar em um dos projetos Spring que trabalhei.

No caso do Spring tradicional com o Hibernate são gerados automaticamente arquivos *.hbm.xml que geram acesso automático ao BD através de uma serialização.


Em um post mais para frente vou abordar internacionalização e sessão de usuário.


Esta implementação especificamente foi retirada da viddeo aula High Tech Cursos:
https://www.youtube.com/watch?v=dg0aZbP8NAU&index=1&list=PLKvsMn7xWutbSELeX5j8CXF2Lxd2cj19J

2 comentários:

  1. Muito bom! Me ajudou muito! Obrigado pelas informações!

    ResponderExcluir
  2. Sempre quando alguém me pede algo básico sobre o spring boot eu indico esse post porque explica corretamente para o pessoal iniciante. Gostaria de deixar a recomendação para o pessoal que está começando também fazerem o download gratuito do e-boo API RESTful com Spring Boot no link → https://www.javaavancado.com/ebook-spring-boot/index.html

    ResponderExcluir