terça-feira, 24 de março de 2015

Mapeamento objeto-relacional com JPA

Olá amigos do Preciso Estudar Sempre. Hoje falaremos sobre um assunto que muitas pessoas não conhecem de forma plena e só sabem utilizar copiando e colando soluções de outras pessoas. Hoje falaremos sobre mapeamento objeto-relacional com JPA. Mas, antes de tudo, vamos definir o que é o mapeamento objeto relacional.

Mapeamento objeto-relacional é técnica de desenvolvimento que possibilita utilizar a orientação à objetos em sua base de dados relacional mas, como isso funciona? Vamos supor que temos a tabela pessoa e que nesta tabela existem diversas colunas. Utilizando a ORM (Object-Relational Mapping), ou seja, o mapeamento objeto-relacional é possível criar uma classe Pessoa a qual, representará a tabela e com atributos os quais, representarão as colunas.

Esqueça a forma tradicional de se trabalhar com banco de dados. Quando se usa ORM, é somente necessário realizar alterações em nossas coleções de objetos que isto será refletido automaticamente no banco de dados e quando for necessário realizar querys, isso também não será feito da forma tradicional. Antes você manipulava tabelas, agora você manipula classes.

Neste post não abordaremos como realizar querys usando ORM, isto ficará para um próximo post. Hoje entenderemos o básico para poder evoluir depois.

Bem, vamos voltar ao assunto e eis aqui o nosso exemplo:

Figura 1 - Tabela pessoa
Figura 2 - Classe Pessoa
No exemplo acima temos a tabela pessoa e classe Pessoa, ambas mencionadas acima. Porém, não é necessário somente criar a classe e pronto, está funcionando. Faltam ainda umas coisas. O Java não entende automaticamente que tal classe reflete tal tabela. Para isto acontecer, é necessário anotar nossas classes. Se você não sabe o que é uma anotação, clique aqui e leia sobre o assunto.

As anotações que usaremos pertencem à JPA mas, o que é JPA ? Segundo à wikipedia, a JPA é:
Java Persistence API (ou simplesmente JPA) é uma API padrão da linguagem Java que descreve uma interface comum para frameworks de persistência de dados. A JPA define um meio de mapeamento objeto-relacional para objetos Java simples e comuns (POJOs), denominados beans de entidade. Diversos frameworks de mapeamento objeto/relacional como o Hibernate implementam a JPA. Também gerencia o desenvolvimento de entidades do Modelo Relacional usando a plataforma nativa Java SE e Java EE.
A explicação acima é bem clara e agora que já sabemos o que é JPA, podemos aplicar suas anotações na nossa classe Pessoa.

 @Entity  
 @Table(name="pessoa") 
 public class Pessoa implements Serializable{ 

      @Id 
      @Column(name="id", nullable=false) 
      @GeneratedValue(strategy = GenerationType.AUTO) 
      private Long id; 

      @Column(name="nome", nullable = false, length=100) 
      private String nome; 

      @Temporal(TemporalType.DATE) 
      @Column(name = "dataNasc", nullable = false) 
      private Date dataNascimento; 

      private String email; 

      @Column(name="altura", precision=2) 
      private Double altura; 

      @Column(name="peso", precision=3) 
      private Double peso; 

      @Column(name="rg", length=9, unique=true) 
      private Integer rg; 

     /*métodos gets e sets*/ 

 } 

Você deve ter notado que aplicamos várias anotações na nossa classe, vamos entender uma por uma:

@Entity -> Anotação de escopo de classe. Representa que nossa classe será uma entidade a qual, reflete uma entidade do banco de dados e assim, poderemos manipulá-las em querys e outras operações.
@Table -> Anotação de escopo de classe. Representa que nossa entidade refletirá uma tabela do banco de dados e é onde será definido mais informações sobre a tabela alvo.
  • name: Representa o nome da tabela.
@Id -> Anotação de escopo de atributo. Representa que aquele atributo refletirá a PK da nossa tabela.
@Column -> Anotação de escopo de atributo. Representa que o nosso atributo refletirá uma coluna do banco de dados.
  • name: Representa o nome da coluna.
  • nullable: Flag que representa que a coluna aceita valores nulos. Caso seja false, a coluna/atributos não aceita valores nulos, caso contrário, aceita.
  • length: Tamanho da coluna no banco de dados.
  • precision: Usado para valores de ponto flutuante. Representa a quantidade de casas decimais da coluna.
  • unique: Representa que a coluna é uma unique key
@GeneratedValue -> Anotação de escopo de atributo. O atributo que é marcado com essa anotação terá valores gerados automaticamente. Essa anotação é usada para PKs autoincrement.
  • strategy: Representa a forma que os valores serão gerados, podem ser gerador de forma automática, através de sequence, entre outras formas.
@Temporal -> Anotação de escopo de atributo. Esta anotação representa que a coluna será do tipo date.

Você deve ter notado que o atributo email não foi mapeado. Isto não está errado e foi feito de propósito. Quando sua classe é carregada e a JPA vê que um dos atributos não foi mapeado, ela procura uma coluna no banco de dados com o mesmo nome do atributo. Como é possível notar na figura 1, realmente existe uma coluna com o nome de email logo, isto não ocasionará em nenhum erro.

Porém, se você possuir em sua classe um atributo não mapeado e a JPA não encontrar nenhuma coluna que tenha o mesmo nome, isto ocasionará um erro. Atributos não mapeados que não representam colunas do banco de dados devem ser anotados com a anotação @Transient a qual, representa que um determinado atributo de uma classe serve para o transporte de dados (DTO).

Obviamente que existem milhares de anotações e eu não sei todas até porque, isso é humanamente impossível. Neste post, eu abordei as principais, as que são mais usadas nos projetos.

Deixo aí embaixo linkado um post que foi feito aqui no blog em que discutimos sobre outras anotações da JPA. Caso você queira um livro para aprender mais sobre as anotações da JPA, dê uma olhada neste post:
Roteiro de estudo para o livro EJB 3 Profisional - Java Persistence API: http://precisoestudarsempre.blogspot.com.br/2013/09/roteiro-de-estudo-para-o-livro-ejb-3.html

Para baixar o projeto pronto, clique aqui.

Sugestões ?! Críticas ?! Elogios ?! 

Deixe aí nos comentários ou na nossa página do facebook.


Referências:
Criar anotações, é possível ?: http://precisoestudarsempre.blogspot.com.br/2015/03/criar-anotacoes-e-possivel.html
@Embeddable e @Embedded no JPA: http://precisoestudarsempre.blogspot.com.br/2015/02/embeddable-e-embedded-no-jpa.html
Documentação @Column: http://docs.oracle.com/javaee/5/api/javax/persistence/Column.html
Documentação @Entity: http://docs.oracle.com/javaee/5/api/javax/persistence/Entity.html
Documentação @Table: http://docs.oracle.com/javaee/5/api/javax/persistence/Table.html
Documentação @Transient: http://docs.oracle.com/javaee/5/api/javax/persistence/Transient.html
Leia Mais ››

terça-feira, 17 de março de 2015

Regex para validação de código hexadecimal HTML

Galera, bem vindo ao Preciso Estudar Sempre. Esse post é da série de dicas rápidas que temos aqui no blog.

Vamos supor que você está desenvolvendo algum tipo de color picker e precisa validar as cores que foram expressadas através de codificação hexadecimal. Como você vai validar isso ?

É possível realizar a validação desta máscara de forma programática mas, imagina só que trabalhão isso vai dar. É muito mais fácil você aplicar uma regex para realizar essa validação.

A regex que você precisa está aqui.

 ^#([a-fA-F0-9]){3}(([a-fA-F0-9]){3})?$  

Vou deixar aí embaixo, linkado, referências para outros post aqui do blog que falam sobre regex.

Sugestões ?! Críticas ?! Elogios ?! 

Deixe aí nos comentários ou na nossa página do facebook.


Regex para endereço MAC: http://precisoestudarsempre.blogspot.com.br/2015/01/regex-para-endereco-mac.html
Regex para validar URL: http://precisoestudarsempre.blogspot.com.br/2014/11/regex-para-validar-url.html
Regex para identificar possíveis causas de NullPointerException: http://precisoestudarsempre.blogspot.com.br/2014/11/regex-para-identificar-possiveis-causas.html
Máscara para RG e CPF: http://precisoestudarsempre.blogspot.com.br/2014/09/mascara-para-rg-e-cpf.html
Regex para horas - Máscara para horas: http://precisoestudarsempre.blogspot.com.br/2013/06/regex-para-horas-mascara-para-horas.html
Máscara para valores decimais negativos: http://precisoestudarsempre.blogspot.com.br/2013/03/mascara-para-valores-decimais-negativos.html
Leia Mais ››

sexta-feira, 13 de março de 2015

Um primeiro contato: PHP

Bem vindo ao Preciso Estudar Sempre. O tema dessa semana será algo nunca visto aqui antes. Hoje falaremos de uma linguagem de programação a qual, não é Java. Hoje, falaremos de PHP mas, porque PHP ? Porque essa mudança agora ? Bem, vamos às respostas !

Pergunta: porque PHP ?
Resposta: Escolhi PHP porque é uma linguagem que é muito usada, rápida, fácil e poderosa. Já faz tempo que eu quero aprender e falar sobre PHP.

Pergunta: Porque essa mudança agora ?
Resposta: Resolvi realizar essa mudança para que todos nós possamos aprender coisas novas visando, adicionar ao nosso canivete novos conhecimentos.

Para quem não está se aguentando, clique aqui e baixe o projeto.

Não fique achando que você terminará de ler esse post e será considerado um expert PHP. O que iremos abordar aqui é um exemplo simples. O começo da estrada do aprendizado.

O PHP é uma linguagem de programação que não é compilada, é interpretado. Você escreve seu código e põe ele no servidor de aplicações e pronto ! Está funcionando !

Com isso, nosso processo de desenvolvimento será mais rápido que o Java. O servidor de aplicações é o responsável por analisar o que escrevemos e interpretar os comandos utilizados. O PHP em sua versão 5 oferece suporte a orientação à objetos. Porém, ela não foi feita para ser OO. Existe uma grande diferença entre você ter uma linguagem que nasceu OO e uma linguagem que oferece suporte à OO.

OBS.: Para falar de OO, usaremos o Java como exemplo.

Enquanto no Java, você é obrigado a criar no mínimo uma classe com um método para começar a trabalhar, no PHP você não precisa disso. Basta somente, criar um arquivo com extensão .php, abrir um editor de texto qualquer e começar a programar ali. Obviamente que existem vantagens e desvantagens. O Java é fortemente OO e compilado, ele te oferece uma organização e uma estrutura bem definida mas, o desenvolvimento no PHP é muito mais rápido mas, você abre mais brechas à uma programação mal feita.

Desapegue da idéia da linguagem perfeita. Isso não existe. Em TI não existem balas de prata.

Para começarmos a desenvolver em PHP, precisaremos das ferramentas abaixo:
  • Um editor de texto (Sublime Text).
  • Um programa que tenha servidor de aplicações, banco de dados e administração de dados (WAMP ou EasyPHP). Eu uso o EasyPHP.
  • Um navegador.
IMPORTANTE: Se você já tiver o MySQL instalado na sua máquina, você vai precisar terminar o processo dele para que o WAMP ou o Easy possa levantar seu próprio processo do MySQL. Se você não fizer isso o WAMP ou Easy não vai conseguir realizar o start.

Vamos por mãos à obra.

Crie uma pasta na pasta de projetos da ferramenta (WAMP ou Easy) e escolha um nome para o seu projeto. Caso seja o WAMP é a pasta www, caso seja o Easy é a pasta projects.

Pasta de projetos
O projeto PHP
Dentro da pasta do projeto crie três pastas: controller, view e model.

Pacotes do projeto
Dentro da pasta controller, crie o arquivo Controller.php, dentro da pasta view, crie a página pagina.html e dentro da pasta model crie o arquivo Cliente.php.

pagina.html
 <!DOCTYPE html>  
 <html> 
 <head> 
      <title>Preciso Estudar Sempre</title> 
 </head> 
 <body> 
      <form method="POST" action="../controller/Controller.php">           
           <div>               
                <label for="nome">Nome</label> 
                <input type="text" name="nome" /> 
           </div> 
           <div>               
                <label for="email">Email</label> 
                <input type="text" name="email" /> 
           </div> 
           <div>               
                <label for="dtNascimento">Data de nascimento</label> 
                <input type="text" name="dtNascimento" /> 
           </div> 
           <div>               
                <label for="rg">RG</label> 
                <input type="text" name="rg" /> 
           </div> 
           <div>               
                <label for="cpf">CPF</label> 
                <input type="text" name="cpf" /> 
           </div> 
           <input type="submit" value="Confirmar" /> 
      </form> 
 </body> 
 </html> 

Cliente.php
 <?php   

 /** 
 *  
 */ 
 class Cliente { 
      private $id; 
      private $nome; 
      private $email; 
      private $dtNascimento; 
      private $RG; 
      private $CPF; 

      function __construct() { } 

      public function getId(){ 
           return $this->id; 
      } 

      public function setId($id){ 
           $this->id=$id; 
      } 

      public function getNome(){ 
           return $this->nome; 
      } 

      public function setNome($nome){ 
           $this->nome=$nome; 
      } 

      public function getEmail(){ 
           return $this->nome; 
      } 

      public function setEmail($email){ 
           $this->email=$email; 
      } 

      public function getDtNascimento(){ 
           return $this->dtNascimento; 
      } 

      public function setDtNascimento($dtNascimento){ 
           $this->dtNascimento=$dtNascimento; 
      } 

      public function getRG(){ 
           return $this->RG; 
      } 

      public function setRG($RG){ 
           $this->RG=$RG; 
      } 

      public function getCPF(){ 
           return $this->CPF; 
      } 

      public function setCPF($CPF){ 
           $this->CPF=$CPF; 
      } 
 } 
  ?> 

Controller.php
 <?php   

 /** 
 *  
 */ 
 require_once("../model/Cliente.php"); 

 class Controller { 

      function __construct() { } 

      public function exibirDados(){ 
           $cliente = $this->construirCliente($_REQUEST); 
           echo "<h1>Dados do cliente</h1> <br/>"; 
           echo "Id: " . $cliente->getId() . "<br/>"; 
           echo "Nome: " . $cliente->getNome() . "<br/>"; 
           echo "Email: " . $cliente->getEmail() . "<br/>"; 
           echo "Data de nascimento: " . $cliente->getDtNascimento() . "<br/>"; 
           echo "RG: " . $cliente->getRG() . "<br/>"; 
           echo "CPF: " . $cliente->getCPF() . "<br/>"; 
      } 

      public function construirCliente($request){ 
           $cliente = new Cliente();           
           $cliente->setId(1); 
           $cliente->setNome($request['nome']); 
           $cliente->setEmail($request['email']); 
           $cliente->setDtNascimento($request['dtNascimento']); 
           $cliente->setRG($request['rg']); 
           $cliente->setCPF($request['cpf']); 
           return $cliente; 
      } 
 } 
 $controller = new Controller(); 
 $controller->exibirDados(); 
  ?> 

Vamos às explicações !!

Você já deve estar irritado com o $ em todo o canto no código. Isso acontece porque em PHP as referências à variáveis são feitas com o cifrão, ou seja, toda variável ou atributo deve usar o cifrão. Outra coisa que você deve ter reparado foi a seta usada. A seta (->) é usada para acesso de métodos e atributos, é igual ao ponto (.) do Java.

Em Java: meuObjeto.foo();

Em PHP: $meuObjeto->foo();

IMPORTANTE: PHP não é case sensitive, ou seja, acessar o método getNome ou getnome resulta na mesma coisa.

O construtor da classe é representado function __construct() { } e ele se comporta como um construtor qualquer. Porém, PHP não suporta sobrecarga logo, você não conseguirá criar vários construtores e métodos com o mesmo nome.

Outro ponto peculiar é no uso do comando echo. Este comando serve para imprimir informações. O ponto serve para realizar a concatenação dos dados assim como, o + é usado no System.out.println do Java.

Para acessar elementos da própria classe, ou seja, atributos e métodos, deve-se usar o $this->meuMetodo ou $this->meuAtributo. Isto acontece porque o PHP não consegue associar automaticamente que, chamadas à metodos ou atributos que não são precedidos de um objeto são da própria classe ou de uma superclasse.

Como é possível concluir, é necessário muito pouco para criar um projeto php e muito pouco para realizar seu deploy. Espero que este post tenha sido um ótimo guia introdutório para o desenvolvedor que nunca teve contato com a linguagem.

Sugestões ?! Críticas ?! Elogios ?! 

Deixe aí nos comentários ou na nossa página do facebook.


Referências:
http://php.net/docs.php - Documentação oficial do PHP
http://www.w3schools.com/php/default.asp
Leia Mais ››

segunda-feira, 2 de março de 2015

Criar anotações, é possível ?

Sejam bem-vindos ao Preciso Estudar Sempre !!

Diversas vezes no desenvolvimento de um software, é comum o uso de anotações ou annotations. Mas, você sabe o que é uma annotation ? Você já criou uma alguma vez? Então, no post dessa semana falaremos sobre a criação de annotations e iremos entender como elas funcionam.

Já adianto logo, esse post é de nível intermediário. Então, eu espero que você já possua alguns conhecimentos sobre Java. Como foi citado no Preciso Estudar Sempre:@Embeddable e @Embedded no JPA, uma annotation é uma forma dinâmica de definição de metadata.

Para download do projeto pronto, clique aqui.

Antigamente os metadados eram definidos via XML mas, isso era muito trabalhoso e a oportunidade de cometer um erro era grande. Como sabemos, metadata é nada mais nada menos que, um dado sobre um dado. Mas, o que é um dado sobre um dado? Segundo a wikipedia, a definição de metadado é:
Metadados, ou Metainformação, são dados sobre outros dados. Um item de um metadado pode dizer do que se trata aquele dado, geralmente uma informação inteligível por um computador. Os metadados facilitam o entendimento dos relacionamentos e a utilidade das informações dos dados.
Como isso pode ser refletido no ambiente de desenvolvimento ? Vamos supor que exista uma classe chamada Morador.java e uma classe Carro.java. Elas fazem parte de um sistema de condomínio. Um morador possui um carro. Na classe de morador iremos definir metadados, como:
  • Data inicial de morada (quando ele começou a morar nesse condomínio)
  • Se é inquilino ou não
Na classe de carro iremos definir:
  • Numeração da documentação do carro
  • Placa do carro
IMPORTANTE: Isto é exemplo. Para esta situação, talvez a melhor abordagem(Morador e Carro) não seja annotation.

Agora que já sabemos quais metadados pertencem ao morador e ao seu carro, podemos criar nossas annotations.

CarroAnnotation.java
 package pkg;  
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;

 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.FIELD)
 public @interface CarroAnnotation {
      String numeracaoDocumentoCarro();
      String placa();
 }

MoradorAnnotation.java
 package pkg;  
 import java.lang.annotation.ElementType; 
 import java.lang.annotation.Retention; 
 import java.lang.annotation.RetentionPolicy; 
 import java.lang.annotation.Target; 

 @Target(ElementType.TYPE) 
 @Retention(RetentionPolicy.RUNTIME) 
 public @interface MoradorAnnotation { 
      String dataInicialMoradia(); 
      boolean isInquilino() default false; 
 } 

Neste momento, você deve estar se perguntando: "Ainnnn João, o que é esse @Target e esse @Retention ??????"

Para você definir uma anotação, você precisa definir como o compilador e JVM interpretarão ela e aonde ela será aplicada. Essas anotações servem para isso.

@Target = Aonde sua annotation será aplicada.
ElementType.TYPE -> será uma anotação de classe, interface ou enum;
ElementType.FIELD -> será uma anotação de atributo;
ElementType.METHOD -> será uma anotação de método;
ElementType.CONSTRUCTOR -> será uma anotação de construtor;
ElementType.ANNOTATION_TYPE -> será uma anotação de anotação;
ElementType.LOCAL_VARIABLE -> será uma anotação de variável local;
ElementType.PACKAGE -> será uma anotação de pacote;
ElementType.PARAMETER -> será uma anotação de parâmetro.

@Retention = Como a annotation será interpretada
RetentionPolicy.SOURCE -> será utilizada apenas no código fonte: é descartada pelo compilador e pela VM;
RetentionPolicy.CLASS -> será gravada na classe, mas não será utilizada pela VM;
RetentionPolicy.RUNTIME -> será gravada na classe e utilizada pela VM, assim, pode ser lida por reflexão.

Agora que já temos nossas annotations prontas, podemos aplicá-las às nossas classes.

Carro.java
 package pkg; 

 public class Carro {
      private String modelo;
      private String marca;
      private String ano;
      private String placa;

      public String getModelo() {
           return modelo;
      }

      public void setModelo(String modelo) {
           this.modelo = modelo;
      }

      public String getMarca() {
           return marca;
      }

      public void setMarca(String marca) {
           this.marca = marca;
      }

      public String getAno() {
           return ano;
      }

      public void setAno(String ano) {
           this.ano = ano;
      }

      public String getPlaca() {
           return placa;
      }

      public void setPlaca(String placa) {
           this.placa = placa;
      }
 }

Morador.java
 package pkg;  

 @MoradorAnnotation(isInquilino=true, dataInicialMoradia="01/02/1980") 
 public class Morador { 
      private String nome; 
      private String apartamento;
 
      @CarroAnnotation(numeracaoDocumentoCarro="04958JDKDM9485", placa="KDI-9930") 
      private Carro carro; 

      public String getNome() { 
           return nome; 
      } 

      public void setNome(String nome) { 
           this.nome = nome; 
      } 

      public String getApartamento() { 
           return apartamento; 
      } 

      public void setApartamento(String apartamento) { 
           this.apartamento = apartamento; 
      } 

      public Carro getCarro() { 
           return carro; 
      } 

      public void setCarro(Carro carro) { 
           this.carro = carro; 
      } 
 } 

Pronto, nosso projeto está pronto !! Já criamos as annotations, aplicamos nas nossas classes mas falta uma coisa. Como iremos recuperar os valores que aplicamos nas anotações ??

Podemos recuperar os valores através de reflexão. Porém, isto só é possível pois configuramos nossas anotações como RetentionPolicy.RUNTIME. Lembre-se disso pois é importante.

Main.java
 package pkg;  

 import java.lang.annotation.Annotation; 
 import java.lang.reflect.Field; 

 public class Main { 
      public static void main(String[] args) { 
           new Main().exibeValoresAnnotation(); 
      } 

      public void exibeValoresAnnotation(){ 
           Class clazz = Morador.class; 

           if(clazz.isAnnotationPresent(MoradorAnnotation.class)){ 
                Annotation a = clazz.getAnnotation(MoradorAnnotation.class); 
                MoradorAnnotation m = (MoradorAnnotation) a; 
                System.out.printf("Data inicial de moradia: '%s'%n", m.dataInicialMoradia()); 
                System.out.printf("Inquilino: '%s'%n", m.isInquilino()); 
           } 

           for(Field attr : clazz.getDeclaredFields()){ 
                attr.setAccessible(true); 
                if(attr.isAnnotationPresent(CarroAnnotation.class)){ 
                     CarroAnnotation carroAnnotation = (CarroAnnotation) attr.getAnnotation(CarroAnnotation.class); 
                     System.out.printf("Placa: '%s'%n", carroAnnotation.placa()); 
                     System.out.printf("Numeração: '%s'%n", carroAnnotation.numeracaoDocumentoCarro()); 
                } 
           } 
      } 
 } 

Viu como é fácil ? Agora pense que todos aqueles frameworks famosos que você usa, usam essa técnica para classes anotadas. Talvez agora, aquela idéia que você tenha de que os frameworks usam códigos super complexos, não é tão real assim né.

Sugestões ?! Críticas ?! Elogios ?! 

Deixe aí nos comentários ou na nossa página do facebook.


Referência:
http://pt.wikipedia.org/wiki/Metadados
http://blog.hallanmedeiros.com/2009/06/11/criar-anotacoes-em-java/
http://www.mkyong.com/java/java-custom-annotations-example/
Leia Mais ››