terça-feira, 31 de maio de 2011

Validado campo único com hibernate + Seam.

É possível validar que um campo seja único com o hibernate de uma maneira muito simples criando uma anotação hibernate, e a melhor parte é que depois de criado é possível utilizar de uma maneira muito simples para validar qualquer campo.

Vou mostrar como fazer isso utilizando o Hibernate + Seam.

Temos a nossa Entity com os seguintes campos.

@Entity
public class Cliente{

   private String nome;
   private Integer idade;

   //getters e setters
}
Queremos que o nosso campo Nome seja unico, não havendo 2 registros com o mesmo nome.
Para isso vamos criar uma anotação chamada @Unique.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ValidatorClass(UniqueImpl.class)
public @interface Unique {

   String message() default "Campo já existe";

   String classe();

   String campo();

}

Com a nossa annotation criada vamos criar nossa validação da anotação.

@Name("UniqueValidator")
public class UniqueImpl implements Validator<Unique>, PropertyConstraint {

   private String classe;
   private String campo;

   public void initialize(Unique arg) {
      targetEntity = ((Unique)arg).entityName();
      field = ((Unique)arg).fieldName();
   }

   public boolean isValid(Object obj) {
      EntityManager entityManager = (EntityManager) Component.getInstance("entityManager");
      Query query = entityManager.createQuery("select t from " + targetEntit + " t where t." + field + "  = :value");
      query.setParameter("value", obj);

   try {
      query.getResultList();
      return false;
   } catch (final NoResultException e) {
      return true;
   }
   }

   public void apply(Property arg0) {

   }
}
Vamos entender o que acontece na classe de validação da anotação.
É extendido as interfaces Validator<Unique>, PropertyConstraint e implementado os seus metodos.
No metodo initialize são passado os 2 parâmetros que devem ser passados para a anotação funcionar.
No metodo isValid é feito uma query com os 2 parâmetros que serão passados pela annotations (classe e campo)

A annotation esta criada, agora basta implementa-la na nossa entity.
@Unique(classe="org.domain.teste.entity.Cliente", campo="nome", message="Nome já existe")
public String getNome() {
   return nome;
}


E na nossa view



Nome

   
   inputWidth="200px;" id="nome" value="#{cliente.nome}"
  required="true" />
   
   

Pronto a annotations esta pronta e funcionando, e pode ser usada para validar a unicidade de qualquer campo.

sábado, 28 de maio de 2011

Classificando com comparator

Assim como o comparable o comparator é outro modo de classificar uma coleção de uma série de modos diferentes, ao contrario da comparaple é possível classificar até mesmo classes que você não consegue modificar.

Um pequeno exemplo de como implementar o comparator classificando por nome.

public class Cliente{
   private String nome;
   private int idade;

   //Getters e Setters
}

public class NomeSort implements Comparator<Cliente>{
   public String compare(Cliente one, Cliente two){
      return one.getNome().compareTo(two.getNome());
   }
}


public class Teste {

public static void main(String[] args) {
List<Cliente> clientes = new ArrayList<Cliente>();

Cliente c1 = new Cliente();
c1.setNome("Xuxa");
clientes.add(c1);

Cliente c2 = new Cliente();
c2.setNome("Cristiano");
clientes.add(c2);

System.out.println("--- Antes de classificar ---");
for(Cliente c : clientes){
System.out.println(c.getNome());
}

NomeSort ns = new NomeSort();
Collections.sort(clientes, ns);
System.out.println("--- Depois de classificar ---");
for(Cliente c : clientes){
System.out.println(c.getNome());
}
}
}

Ambas interfaces são semelhantes, porem existe algumas diferenças entre elas.

Pacote
Comparable: java.lang.Comparable
Comparator: java.util.Comparator


Implementação
Comparable: int objOne.compareTo(objTwo)
Comparator: int compare(objOne, objTwo)

Retorna
Comparable: negativo se objOne < objTwo, zero se objOne == objTwo, positivo se objOne > objTwo
Comparator: mesmo que comparable

Implementação de classes
Comparable: Você precisa modificar qual a classe cujas instância deseja classificar.
Comparator: Você cria uma classe separada daquela cjas instancias deseja classificar.


Quantidade de seqüencias
Comparable: Só pode ser criada uma seqüencia de classificação.
Comparator: Podem ser criadas varias seqüencias de classificação.

sábado, 21 de maio de 2011

Classificando Lista com Comparable

Nesse post mostrarei como classificar uma Collection (organizar em ordem alfabetica, etc).

Vamos começar com algo facíl, organizar uma lista de Strings, para isso a classe java.util.Collections nos fornece o método sort();



public class Teste {
public static void main(String[] args) {
List<String> nomes = new ArrayList<String>();
nomes.add("Zeca");
nomes.add("Cristiano");
nomes.add("Adriana");
nomes.add("Joao");
System.out.println("Não classificado: " + nomes);
Collections.sort(nomes);
System.out.println("Classificado: " + nomes);
}
}

Iremos ter como retorno


Não classificado: [Zeca, Cristiano, Adriana, Joao]
Classificado: [Adriana, Cristiano, Joao, Zeca]

Agora vamos começar a complicar um pouco.
Queremos classificar uma lista de Objectos de Clientes, pelo nome por exemple.

public class Cliente {
private String nome;
private Integer idade;

       //Getters e Setters
}

Se fizermos como fizemos com String teremos erro de compilação

public class Teste {
public static void main(String[] args) {
List<Cliente> clientes = new ArrayList<Cliente>();
Cliente c1 = new Cliente();
c1.setNome("Zeca");
c1.setIdade(24);
clientes.add(c1);
Cliente c2 = new Cliente();
c2.setNome("Cristiano");
c2.setIdade(22);
clientes.add(c2);
Cliente c3 = new Cliente();
c3.setNome("Joao");
c3.setIdade(43);
clientes.add(c3);
                Collections.sort(clientes);        //ERRO DE COMPILAÇÃO

}

Porque isso acontece?
Se você ler o método sort(), você vai ver que a Collection (no nosso caso o Cliente) deve implementar a interface comparable, a String implementa o comparable por isso conseguimos utilizar o sort() com ele, então é simples se você quer utilizar o sort() com o Cliente basta implementar o comparable na classe Cliente, vou mostrar como fazer isso.

public class Cliente implements Comparable<Cliente>{
private String nome;
private Integer idade;

        //Getters e Setters

       @Override
public int compareTo(Cliente o) {
return nome.compareTo(o.getNome());
}
}

Ao implementar o comparable devemos implementar na classe o método compareTo(), com isso estamos classificando nossa lista por nome (poderíamos fazer também com idade sem problemas). Agora podemos utilizar o Collections.sort(clientes) sem problemas que não teremos nenhum erro de compilação. Vou mostrar como fazer e como fica e ainda como fazer em ordem decrescente, basta utilizar o Cllections.reverse(clientes).

public class Teste {
public static void main(String[] args) {
List<Cliente> clientes = new ArrayList<Cliente>();
Cliente c1 = new Cliente();
c1.setNome("Zeca");
c1.setIdade(24);
clientes.add(c1);
Cliente c2 = new Cliente();
c2.setNome("Cristiano");
c2.setIdade(22);
clientes.add(c2);
Cliente c3 = new Cliente();
c3.setNome("Joao");
c3.setIdade(43);
clientes.add(c3);
System.out.println("---------\nNão Ordernado\n---------");
for (Cliente c : clientes) {
System.out.println("Nome: " + c.getNome());
System.out.println("Idade: " + c.getIdade());
}
System.out.println("---------\nOrdernado\n---------");
Collections.sort(clientes);
for (Cliente c : clientes) {
System.out.println("Nome: " + c.getNome());
System.out.println("Idade: " + c.getIdade());
}
                System.out.println("---------\nOrdernado Decrescente\n---------");
Collections.sort(clientes);
Collections.reverse(clientes);
for (Cliente c : clientes) {
System.out.println("Nome: " + c.getNome());
System.out.println("Idade: " + c.getIdade());
}

}
}

Teremos como resultado.

---------
Não Ordernado
---------
Nome: Zeca
Idade: 24
Nome: Cristiano
Idade: 22
Nome: Joao
Idade: 43
---------
Ordernado
---------
Nome: Cristiano
Idade: 22
Nome: Joao
Idade: 43
Nome: Zeca
Idade: 24
---------
Ordernado Decrescente
---------
Nome: Zeca
Idade: 24
Nome: Joao
Idade: 43
Nome: Cristiano
Idade: 22


No próximo post irei mostrar o Comparator e as diferenças entre Comparator e Comparable


Trabalhando com List e banco de dados

Nesse post irei demonstrar como trabalhar com List, mais especificamente ArrayList.
Para começar vou demonstrar como fazer um Select em uma tabela no banco de dados e armazenar em uma ArrayList.

Para começar vamos criar nossa classe para conecção com o banco de dados, estarei utilizando o mysql


public class ConnectionFactory {
 public static Connection getConnection(){
  Connection cnn = null;
   try{
    Class.forName("com.mysql.jdbc.Driver").newInstance();
    cnn = DriverManager.getConnection("jdbc:mysql://localhost/crud", "root", "root");
   } catch (Exception e) {
    e.printStackTrace();
   }
  return cnn;
 }
}



Temos a seguinte tabela no banco de dados, Cliente com os campo Nome e Idade, vamos implementa-la no java.


public class Cliente {
 
   private String nome;
   private Integer idade;

   //Getters e Setters

}

Insira alguns dados no banco de dados

Insert into Cliente values ('Cristiano', 22);

Insert into Cliente values ('Fabio', 15);

Insert into Cliente values ('Joao', 135);

Insert into Cliente values ('Pedro', 11);

Insert into Cliente values ('Maria', 53);


Agora vamos criar nossa classe que ira fazer o select e armazenar na ArrayList


public class ClienteCrud {
 
 public List<cliente> clientes = new ArrayList<cliente>();

 public void listar(){
  ResultSet rs = null;
  Connection cnn = ConnectionFactory.getConnection();
  try {
   PreparedStatement sql = cnn.prepareStatement("select * from cliente");
   rs = sql.executeQuery();
   while(rs.next()){
    Cliente cliente = new Cliente();
    cliente.setNome(rs.getString("nome"));
    cliente.setIdade(rs.getInt("idade"));
    clientes.add(cliente);
   }
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
}

Vamos entender o que acontece na classe ClienteCrud, é criar uma ArrayList de Cliente, isso significa que só é possível inserir objetos do tipo Cliente nessa lista.
No metodo Listar é criado um ResultSet para armazenar o resultado do select, é feito a connecção com o banco de dados, após isso fazemos o select, executamos a query  guardamos o resultado no ResultSet, agora vamos a parte em que armazenamos o resultado(s) no arrayList.
Fazemos um while(rs.next()) que significa que enquanto existir um próximo resultado ele vai continuar fazendo o loop, agora a parte que nos interessa, é criado um novo objeto Cliente setado o nome e a idade com o resultado do select e adicionado o Objeto Cliente a lista.

Agora vamos finalmente mostrar esse resultado na tela

public class ClienteView {

 public static void main(String[] args) {
  ClienteCrud cc = new ClienteCrud();
  cc.listar();
  System.out.println("--------\nSem Classificação \n--------");
  for (Cliente c : cc.clientes) {
   System.out.println(c.getNome());
   System.out.println(c.getIdade());
  }
 }
}

Iremos obter


--------
Sem Classificação
--------
Nome: Cristiano
Idade: 22
Nome: Fabio
Idade: 15
Nome: Joao
Idade: 135
Nome: Pedro
Idade: 11
Nome: Maria
Idade: 53

No proximo post irei demostrar como fazer a classificação dessa lista com Comparator e Comparable.