Prática 3: Mapeamento Objeto-Relacional (Object-Relational Mapping, ORM) Como o banco de dados é relacional e a linguagem de programação é orientada a objetos, devemos ter uma representação dos objetos em nossa aplicação, para tanto iremos fazer o mapeamento objeto-relacional, implementando classes que representem as estruturas das tabelas do banco de dados. Para entendermos melhor como funciona a comunicação com o banco de dados, a implementação será manual, somente com as classes mais básicas, sem uso de frameworks e APIs, pois para utilizarmos seria necessário primeiro dominar o código mais básico antes de se pensar em ter produtividade com o uso deles, pois mesmo que os frameworks como JPA e CDI possam tornar o processo de desenvolvimento mais produtivo, caso ocorra algum problema, poderemos perder mais tempo do que se estivermos implementando sem eles. 3.1. Criando representação para o sexo e o estado civil de Clientes A tabela de clientes possui dois campos (sexo e estado civil) em que devemos armazenar somente um código ou sigla de identificação. Para facilitar a implementação deste cenário, o Java fornece um tipo especial denominado enum, em que podemos definir uma lista de constantes e, se necessário, incluir atributos e construtores para a definição mais detalhada da implementação. 3.1.1. Enum Sexo Para criar um novo enum Java, siga os seguintes passos: 1. Crie um pacote Java chamado br.edu.univag.pedido.tipo, para armazenarmos os tipos da nossa aplicação; 2. No pacote criado acima, crie um enum clicando com o botão direito do mouse sobre o pacote e acionando comando Novo > Outros; 3. Selecione a categoria Java, o tipo de arquivo Enum Java e clique no botão Próximo; 4. Informe o nome da classe TipoSexo e clique no botão Finalizar; 5. Inclua no início do enum TipoSexo as seguintes constantes: FEMININO, MASCULINO; 6. Note que não foi necessário definir a visibilidade e nem o tipo de cada literal; 7. Isso acontece porque as literais dentro de um enum Java já são public e final e possuem o mesmo tipo do enum onde foram definidas; 8. Como os enum Java não geram um código interno próprio, é interessante criarmos atributos para que possamos armazenar os dados com os tipos que precisamos para a nossa aplicação; 9. Crie os atributos para o armazenamento da sigla e da descrição de cada tipo de sexo: private final String siglaSexo; private final String descSexo; 9. O compilador irá reclamar que esses dois atributos não foram inicializados pelo construtor, portanto, crie um construtor usando as teclas de atalho <Ctrl> + <Espaço>, selecionando o construtor que recebe os parâmetros para popular os dois atributos: private TipoSexo(String siglaSexo, String descSexo) { this.siglaSexo = siglaSexo; this.descSexo = descSexo; } 10. Agora, o compilador irá reclamar que os valores constantes do enum não podem ser aplicados aos construtores disponíveis, então precisamos alterar esses valores, passando tanto o código como a descrição de cada constante que definimos antes: Programação Comercial Walderson Shimokawa 1 FEMININO("F", "Feminino"), MASCULINO("M", "Masculino"); 11. Como os atributos precisam ser acessados pelas classes do projeto, crie os acessores (somente os getters) para os atributos siglaSexo e descSexo que possuem a visibilidade private, acionando o atalho de teclado <Alt> + <Insert>. 12. Para finalizar, crie um método de classe (static) para permitir que um tipo de sexo seja recuperado através de sua sigla: public static TipoSexo get(String siglaSexo) { TipoSexo resposta = null; for (TipoSexo t : values()) { if (t.getSiglaSexo().equals(siglaSexo)) { resposta = t; } } return resposta; } 13. Confira como ficou o código do enum TipoSexo: package br.edu.univag.pedido.tipo; public enum TipoSexo { FEMININO("F", "Feminino"), MASCULINO("M", "Masculino"); private final String siglaSexo; private final String descSexo; private TipoSexo(String siglaSexo, String descSexo) { this.siglaSexo = siglaSexo; this.descSexo = descSexo; } public String getSiglaSexo() { return siglaSexo; } public String getDescSexo() { return descSexo; } public static TipoSexo get(String siglaSexo) { TipoSexo resposta = null; for (TipoSexo t : values()) { if (t.getSiglaSexo().equals(siglaSexo)) { resposta = t; } } return resposta; } } 3.1.2. Enum Estado Civil Seguindo a mesma sequência, crie o enum para o estado civil (TipoEstadoCivil), obtendo o seguinte códigofonte: Programação Comercial Walderson Shimokawa 2 package br.edu.univag.pedido.tipo; public enum TipoEstadoCivil { SOLTEIRO("S", "Solteiro"), CASADO("C", "Casado"), DIVORCIADO("D", "Divorciado"), VIUVO("V", "Viúvo"), SEPARADO("A", "Separado"), //A inicial S já está em uso em Solteiro UNIAO_ESTAVEL("U", "União Estável"); private final String siglaEstadoCivil; private final String descEstadoCivil; private TipoEstadoCivil(String siglaEstadoCivil, String descEstadoCivil) { this.siglaEstadoCivil = siglaEstadoCivil; this.descEstadoCivil = descEstadoCivil; } public String getSiglaEstadoCivil() { return siglaEstadoCivil; } public String getDescEstadoCivil() { return descEstadoCivil; } public static TipoEstadoCivil get(String siglaEstadoCivil) { TipoEstadoCivil resposta = null; for (TipoEstadoCivil t : values()) { if (t.getSiglaEstadoCivil().equals(siglaEstadoCivil)) { resposta = t; } } return resposta; } } 3.2. Value Objects (VO) Os Value Objects (também conhecido como Data Transfer Objects, DTO) são JavaBeans (não confundir com Enterprise JavaBeans) que representam a abstração dos dados a serem utilizados pela aplicação. Em nossa aplicação, utilizaremos os Value Objects para representar os registros do banco de dados. 3.2.1. O Value Object Cliente Essa JavaBean será uma representação dos dados da tabela cliente, do nosso modelo: 1. Crie o pacote Java chamado br.edu.univag.pedido.vo; 2. Crie uma classe Java chamada Cliente no pacote acima; 3. Crie os atributos para fazer o mapeamento com os campos da tabela: private private private private private private private private int codigo; String nome; String endereco; String numero; String complemento; String cep; String bairro; String cidade; Programação Comercial Walderson Shimokawa 3 private private private private TipoUnidadeFederada uf; String telefone; TipoSexo sexo; TipoEstadoCivil estCivil; 4. Adicione as importações necessárias (enum TipoUnidadeFederada1, enum TipoSexo e enum TipoEstadoCivil), usando o atalho de teclado <Ctrl> + <Shift> + i; 5. Acrescente os métodos acessores (getters e setters) para cada atributo, com a combinação de teclado <Alt> + <Insert>; 6. Pronto, os registros da tabela cliente agora estão representados na nossa aplicação. 3.3. Exercícios 1. Pesquise e responda: por que os construtores dos enum Java possuem a visibilidade private? 2. Crie classes de testes unitários para verificar os métodos do enum TipoSexo e também do enum TipoEstadoCivil. 3. Crie um enum, chamado TipoUnidadeFederada, contendo a sigla (atributo siglaUnidadeFederada) e o nome (atributo nomeUnidadeFederada) dos estados brasileiros. Crie uma classe de testes para este enum também. 4. Pesquise sobre os métodos equals e hashCode, implementados na classe Object e que devem ser sobrescritos em certas subclasses para atender à certas necessidades. Quando eles são necessários? 5. Implemente o JavaBean para a tabela categoria (classe Categoria), com os seguintes atributos: codigo (int) e descricao (String). Não se esqueça de criar os métodos acessores para os atributos. 6. Crie os JavaBeans para representar as tabelas fornecedor, produto, vendedor, pedido, e item_pedido conforme descrito nas tabelas abaixo: Classe: Fornecedor Atributo codigo nome endereco numero complemento cep bairro cidade uf telefone fax Classe: Vendedor Tipo int String String String String String String String TipoUnidadeFederada String String Atributo codigo nome percComissao Tipo int String double Classe: ItemPedido Atributo produto quantidade Tipo Produto int Classe: Pedido Classe: Produto Atributo codigo categoria fornecedor qtdEstoque nome valUnitario 1 Tipo int Categoria Fornecedor int String double Atributo numero vendedor cliente dataPedido dataEntrega itens Tipo int Vendedor Cliente java.util.Date java.util.Date java.util.Collection<ItemPedido> Crie o enum TipoUnidadeFederada seguindo a mesma lógica apresentada para a criação de TipoSexo e TipoEstadoCivil. Programação Comercial Walderson Shimokawa 4 7. As classes Cliente e Fornecedor apresentam muitos atributos em comum. Indique qual conceito de orientação a objetos pode ser aplicado neste cenário, de forma que se possa minimizar o código-fonte construído, facilitando a manutenção. 8. Considerando a resposta da questão anterior, como ficaria o código-fonte das classes Cliente e Fornecedor? 9. Implemente um método chamado getTotal() na classe ItemPedido, calculando o total do item de pedido. 10. Implemente um método chamado getTotal(), na classe Pedido, calculando o total do pedido. 11. Crie as classes de testes para testar as classes criadas nesta prática. 12. Desenhe o diagrama de classes UML das classes criadas nesta prática. Programação Comercial Walderson Shimokawa 5