0% acharam este documento útil (0 voto)
230 visualizações14 páginas

Projeto Java Com Spring

O documento descreve um capítulo sobre implementação de modelo conceitual em Java usando Spring Boot, cobrindo tópicos como: mapeamento de classes, associações, herança, enumerações e mais. O objetivo é mostrar como um modelo conceitual pode ser implementado em orientação a objetos usando boas práticas de engenharia de software.

Enviado por

jandrearaujo
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
230 visualizações14 páginas

Projeto Java Com Spring

O documento descreve um capítulo sobre implementação de modelo conceitual em Java usando Spring Boot, cobrindo tópicos como: mapeamento de classes, associações, herança, enumerações e mais. O objetivo é mostrar como um modelo conceitual pode ser implementado em orientação a objetos usando boas práticas de engenharia de software.

Enviado por

jandrearaujo
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

Curso: Spring Boot com Ionic - Estudo de Caso Completo

[Link]
Prof. Dr. Nelio Alves

Capítulo: Implementação de modelo conceitual

Objetivo geral:

O estudo de caso deste capítulo tem como objetivo mostrar na prática como um modelo conceitual (modelo de
domínio em nível de análise) pode ser implementado sobre o paradigma orientado a objetos, usando padrões de
mercado e boas práticas.

Vamos tomar como caso um modelo conceitual abrangente, com o qual possamos mostrar a implementação prática
em linguagem orientada a objetos dos seguintes tópicos:

 Leitura e entendimento do diagrama de classes


 Leitura e entendimento do diagrama de objetos
 Associações
o Um para muitos / muitos para um
o Um para um
o Muitos para muitos comum
o Muitos para muitos com classe de associação
o Bidirecionais / direcionadas
 Conceito independente / dependente
 Classe de associação
 Herança
 Enumerações
 Atributos Embedded (ItemPedidoPK)
 Coleções ElementCollection (telefones de um cliente)

Ao longo do capítulo também vamos discutir e mostrar boas práticas de Engenharia de Software tais como
desenvolvimento em camadas e tratamento de exceções. A estrutura de camadas do sistema será conforme
mostrado a seguir:
Objetivos específicos:

1) Fazer uma implementação padrão do seguinte modelo conceitual:

Enumerações:
Objetivos (continuação):

2) Criar a seguinte instância do modelo conceitual:

3) Gerar uma base de dados relacional automaticamente a partir do modelo conceitual, bem como povoar a base com a instância dada.

4) Recuperar os dados e disponibilizá-los por meio de uma API Rest BÁSICA. Os seguintes end points devem ser disponibilizados:

End point Dados


/categorias/{id} Categoria e seus produtos
/clientes/{id} Cliente, seus telefones e seus endereços
/pedidos/{id} Pedido, seu cliente, seu pagamento, seus itens de
pedido, seu endereço de entrega
Instalação das ferramentas

ATUALIZAÇÃO
ATENÇÃO: INSTALE A VERSÃO 8 DO JAVA JDK
 Link Java 8 JDK: [Link]

ATENÇÃO AOS BITS DA SUA MÁQUINA (32bits ou 64bits)

 Git
 Conta no Github
 Google Chrome e Postman
 JDK - Java Development Kit
 STS - Spring Tool Suit (Eclipse / Maven / Tomcat / Jackson / JPA)

Ajuste do layout do STS:


 Window -> Perspective -> Open Perspective -> Other -> Spring
 Window -> Perspective -> Reset Perspective
 Minimizar as abas Outline e Spring Explorer

Criação do projeto Spring Boot

ATUALIZAÇÃO
Erro comum: versão do Java JDK
Recomendação: instale o Java versão 8 e 64bits
 Vídeo: [Link]
 Link Java 8 JDK: [Link]

Erro comum: arquivo corrompido do Maven (invalid LOC header)


Recomendação: apague os arquivos e voltar ao STS e deixar o Maven refazer o download
 Vídeo: [Link]

ATENÇÃO: VERSÃO DO SPRING BOOT:


Se, na criação do projeto, você escolher a versão 2.x.x, fique atento(a) às atualizações nos inícios de algumas
aulas!

As atualizações serão mostradas apenas na primeira vez em que elas forem necessárias.

 Botão direito na área da aba Package Explorer -> New -> Spring Starter Project
o Se não aparecer: New -> Other -> Procure

 Opções:
o Name: cursomc
o Type: Maven
o Java Version: 1.8
o Group: [Link]
o Artifact: cursomc
o Version: 1.0.0-SNAPSHOT (é uma convenção do Maven)
o Description: Estudo de caso Java para curso de Modelagem Conceitual com UML
o Package: [Link]
o Next

 Opções
o Spring Boot Version: 1.5.x ou 2.x.x
o Web -> Web

 Botão direito -> Run As -> Spring Boot App


SE OCORRER UM ERRO PORQUE A PORTA 8080 JÁ ESTÁ EM USO, OU PARE A APLICAÇÃO,
OU MUDE A PORTA:
[Link]:
[Link]=${port:8081}

Primeiro commit: Projeto criado

 Iniciar um repositório de versionamento na pasta do projeto:


git init

 Configurar usuário e email (use seu email do Github):


git config --global [Link] "Seu nome"
git config --global [Link] "seuemail@seudominio"

 Fazer o primeiro commit:


git add .
git commit -m "Projeto criado"

Testando o REST

 Arrumando o problema do atalho CTRL + SHIFT + O:


o Preferences -> General -> Keys
o Filters -> desmarque Filter uncategorized commands
o Localize "Go To Symbol in File", selecione-o e clique "unbind"
o Apply / Close

 Classe CategoriaResource (subpacote resources)

package [Link];

import [Link];
import [Link];
import [Link];

@RestController
@RequestMapping(value = "/categorias")
public class CategoriaResource {

@RequestMapping(method=[Link])
public String listar() {
return "REST está funcionando!";
}
}
Testando a primeira classe de dominio - Categoria

 Checklist para criar entidades:


o Atributos básicos
o Associações (inicie as coleções)
o Construtores (não inclua coleções no construtor com parâmetros)
o Getters e setters
o hashCode e equals (implementação padrão: somente id)
o Serializable (padrão: 1L)

 Método listar atualizado:

@RequestMapping(method=[Link])
public List<Categoria> listar() {
Categoria cat1 = new Categoria(1, "Informática");
Categoria cat2 = new Categoria(2, "Escritório");

List<Categoria> lista = new ArrayList<>();


[Link](cat1);
[Link](cat2);

return lista;
}

Banco de dados H2 e criação automática da base de dados

ATUALIZAÇÃO - H2 em alguns sistemas só funcionou assim:


[Link]=true
[Link]=/h2-console

[Link]=jdbc:h2:file:~/test
[Link]=sa
[Link]=
[Link]-class-name=[Link]

[Link]-sql=true
[Link].format_sql=true

# No JDBC URL: jdbc:h2:file:~/test

 Dependências:

<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

 Rodar /h2-console com a base jdbc:h2:mem:testdb

 Mapeamento da classe Categoria:

@Entity
public class Categoria implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=[Link])
private Integer id;

 Alterar o arquivo [Link]

[Link]=jdbc:h2:mem:testdb
[Link]=sa
[Link]=

[Link]-sql=true
[Link].format_sql=true

Criando repository e service para Categoria

ATUALIZAÇÃO
Se você criou o projeto usando Spring Boot versão 2.x.x:
[Link]

Em CategoriaService, onde na aula é mostrado:

public Categoria find(Integer id) {


Categoria obj = [Link](id);
return obj;
}

Troque pelo seguinte código (import [Link]):

public Categoria find(Integer id) {


Optional<Categoria> obj = [Link](id);
return [Link](null);
}
Documentação da classe Optional:
[Link]

Criando operacao de instanciacao

ATUALIZAÇÃO
Se você criou o projeto usando Spring Boot versão 2.x.x:
[Link]

No programa principal, onde na aula é mostrado:

[Link]([Link](cat1, cat2));
Troque pelo seguinte código:

[Link]([Link](cat1,
Texto cat2));

Produto e associacao muitos para muitos

 Mapeamento na classe Produto:

@ManyToMany
@JoinTable(name = "PRODUTO_CATEGORIA",
joinColumns = @JoinColumn(name = "produto_id"),
inverseJoinColumns = @JoinColumn(name = "categoria_id")
)
private List<Categoria> categorias = new ArrayList<>();

 Mapeamento na classe Categoria:

@ManyToMany(mappedBy="categorias")
private List<Produto> produtos = new ArrayList<>();

Ajustes no endpoint /categorias/{id}

ATUALIZAÇÃO
Se você criou o projeto usando Spring Boot versão 2.x.x:
[Link]
Em CategoriaService, onde na aula é mostrado:

public Categoria find(Integer id) {


Categoria obj = [Link](id);
if (obj == null) {
throw new ObjectNotFoundException("Objeto não encontrado! Id: " + id
+ ", Tipo: " + [Link]());
}
return obj;
}

Troque pelo seguinte código:

public Categoria find(Integer id) {


Optional<Categoria> obj = [Link](id);
return [Link](() -> new ObjectNotFoundException(
dssdfdsfsdfsdf
"Objeto não encontrado! Id: " + id + ", Tipo: " + [Link]()));
} dsfsdf
g
 Proteção para referência cíclica na serialização Json:
gssdf
@JsonManagedReference
@JsonBackReference sfs

 Checklist de tratamento de exceção de id sdfsd


inválido:

o Criar ObjectNotFountException
o Criar StandardError
o Criar ResourceExceptionHandler

Estado e Cidade

 Checklist para criar entidades:


o Atributos básicos
o Associações (inicie as coleções)
o Construtores (não inclua coleções no construtor com parâmetros)
o Getters e setters
o hashCode e equals (implementação padrão: somente id)
o Serializable (padrão: 1L)

 Mapeamentos:

@Entity
public class Cidade implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=[Link])
private Integer id;
private String nome;

@ManyToOne
@JoinColumn(name="estado_id")
private Estado estado;
@Entity
public class Estado implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=[Link])
private Integer id; dsfsdfdsgreyerydg
private String nome; dssdgsdgsd
@OneToMany(mappedBy="estado") sdgsd
private List<Cidade> cidades; g

Cliente, TipoCliente, telefones e enderecos

 Implementação do Enum:

package [Link];

public enum TipoCliente {

PESSOAFISICA(1, "Pessoa Física"),


PESSOAJURIDICA(2, "Pessoa Jurídica");

private int cod;


private String descricao;

private TipoCliente(int cod, String descricao) {


[Link] = cod;
[Link] = descricao;
}

public int getCod() {


return cod;
}

public String getDescricao() {


return descricao;
}

public static TipoCliente toEnum(Integer id) {

if (id == null) {
return null;
}

for (TipoCliente x : [Link]()) {


if ([Link]([Link]())) {
return x;
}
}
throw new IllegalArgumentException("Id inválido " + id);
}
}

 Definição do tipo do cliente e seu getter e setter:

private Integer tipo;

public TipoCliente getTipo() {


return [Link](tipo);
}

public void setTipo(TipoCliente tipo) {


[Link] = [Link]();
}

 Mapeamento dos telefones (ElementCollection):

@ElementCollection
sgsdgsdgg
@CollectionTable(name ="TELEFONE") sdgsdg
private Set<String> telefones = new HashSet<>();
sdg
sdgs
Endpoint /clientes/{id} disponivel
gsd
gs
 Checklist:
o Criar ClienteServico dg
o Criar ClienteResource
o Proteger contra serialização Json cíclica

Pedido, EstadoPagamento e Pagamento

CORREÇÃO
Favor usar HH maiúsculo.

Classe principal do projeto:

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm");

 Nota: Mapeamentos de herança:


[Link]

 Classe Pedido:

@Entity
public class Pedido implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=[Link])
private Integer id;

@Temporal([Link])
private Date instante;

@OneToOne(cascade = [Link], mappedBy="pedido")


private Pagamento pagamento;

@ManyToOne
@JoinColumn(name="cliente_id")
private Cliente cliente;

@ManyToOne
@JoinColumn(name="endereco_id")
private Endereco enderecoDeEntrega;

 Classe Pagamento:

@Entity
@Inheritance(strategy = [Link])
public abstract class Pagamento implements Serializable {
private static final long serialVersionUID = 1L;

@Id
private Integer id;

private Integer estado;

@JoinColumn(name="pedido_id")
@OneToOne
@MapsId
private Pedido pedido;

 Classe PagamentoComBoleto:

@Entity
public class PagamentoComBoleto extends Pagamento {
private static final long serialVersionUID = 1L;

@Temporal([Link])
private Date dataVencimento;

@Temporal([Link])
private Date dataPagamento;

public PagamentoComBoleto() {
}

 Classe PagamentoComCartao:

@Entity
public class PagamentoComCartao extends Pagamento {
private static final long serialVersionUID = 1L;

private Integer numeroDeParcelas;

 Instanciação:

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm");

Pedido ped1 = new Pedido(null, [Link]("30/09/2017 10:32"), cli1, e1);


Pedido ped2 = new Pedido(null, [Link]("10/10/2017 19:35"), cli1, e2);

[Link]().addAll([Link](ped1, ped2));

Pagamento pagto1 = new PagamentoComCartao(null, [Link], ped1, 6);


[Link](pagto1);

Pagamento pagto2 = new PagamentoComBoleto(null, [Link], ped2, [Link]("20/10/2017


00:00"), null);
[Link](pagto2);

[Link]([Link](ped1, ped2));
[Link]([Link](pagto1, pagto2));

ItemPedido e ItemPedidoPK

 Classe ItemPedidoPK:

@Embeddable
public class ItemPedidoPK implements Serializable {
private static final long serialVersionUID = 1L;

@ManyToOne
@JoinColumn(name="pedido_id")
private Pedido pedido;

@ManyToOne
@JoinColumn(name="produto_id")
private Produto produto;

ATENÇÃO: no hashCode e equals, incluir ambos objetos associados que identifica o item

 Classe ItemPedido:

@Entity
public class ItemPedido {

@EmbeddedId
private ItemPedidoPK id = new ItemPedidoPK();

private Double desconto;


private Integer quantidade;
private Double preco;

public ItemPedido() {
}

public ItemPedido(Pedido pedido, Produto produto, Double desconto, Integer


quantidade, Double preco) {
super();
[Link](pedido);
[Link](produto);
[Link] = desconto;
[Link] = quantidade;
[Link] = preco;
}

Endpoint /pedidos/{id} disponibilizado

CORREÇÃO
Favor usar HH maiúsculo.

Classe Pedido:

@JsonFormat(pattern="dd/MM/yyyy HH:mm")

 Checklist:
o Criar PedidoServico
o Criar PedidoResource
o Proteger contra serialização Json cíclica

Atualizacao: utilizando somente JsonIgnore

Em teste realizados, o uso de @JsonManagedReference/@JsonBackRefence apresentou alguns problemas com o


envio de dados Json em requisições .

Assim, ao invés de usar @JsonManagedReference/@JsonBackRefence, vamos simplesmente utilizar o


@JsonIgnore no lado da associação que não deve ser serializada. Para isto faça:
 Para cada classe de domínio:
 Apague as anotações @JsonManagedReference existentes
 Troque as anotações @JsonBackRefence por @JsonIgnore

Você também pode gostar