Arquivo

Textos com Etiquetas ‘Hibernate’

Hibernate – Utilizando a api Criteria

27, dezembro, 2009 4 comentários

Esse post faz parte de uma série que estou preparando sobre o hibernate, o primeiro foi sobre a extensão especial Hibernate Spatial e esse segundo irei falar sobre um pouco sobre um poderoso recurso do Hibernate, a API Criteria. Nesse tutorial não irei entrar em detalhes sobre configuração do Hibernate, assume-se que você tem o hibernate pré-configurado, irei apenas falar da API.

Primeiro criaremos nossa entidade exemplo “Cliente” :


package modelo;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 *
 * @author lucas
 */
@Entity
public class Cliente implements Serializable {

    @Id
    @GeneratedValue
    private int id;
    private String nome;
    private int idade;
    private String cpf;
    private double saldo;

    public String getCpf() {
        return cpf;
    }

    public int getIdade() {
        return idade;
    }

    public void setIdade(int idade) {
        this.idade = idade;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

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

    public double getSaldo() {
        return saldo;
    }

    public void setSaldo(double saldo) {
        this.saldo = saldo;
    }
}

Até aqui nada de novo, marcamos a classe com a anotação @Entity, para indicar que é uma entidade e marcamos o atributo id com as anotações @Id e @GeneratedValue, a primeira diz que esse atributo é a chave primaria e segunda que seu valor será gerado automaticamente. O cliente também tem um atributo saldo, que representará um valor de saldo, tecnicamente o cliente não deveria possuir um saldo e sim um objeto conta e a conta possuir um saldo, porém como o objetivo desse tutorial é demonstrar a api Criteria, não me apeguei a regras de modelagem OO.

Agora criaremos a classe HibernateUtil, que irá conter um método estático que devolve um objeto Session. Com essa classe não precisaremos ficar instanciando o objeto Session toda vez que precisarmos acessar o banco. O próprio netbeans tem um assistente que gera automaticamente essa classe.


package util;

import org.hibernate.Session;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;

/**
 * Hibernate Utility class with a convenient method to get Session object.
 *
 * @author lucas
 */
public class HibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static Session getSession() {
        return sessionFactory.openSession();
    }
}

Agora criaremos um Dao genérico com os métodos padrão em todos os DAO’s, evitando assim o trabalho de implementar os mesmos métodos em todos os DAO’s.


package Dao;

import org.hibernate.Session;
import org.hibernate.Transaction;
import util.HibernateUtil;

/**
 *
 * @author lucas
 */
public class Dao<T> {

    private Class classe;
    private Session session;

    protected Session getSession() {
        return session;
    }

    public Dao(Class classe) {
        this.session = HibernateUtil.getSession();
        this.classe = classe;
    }

    public void salvar(T objeto){
        session.save(objeto);
    }

    public void remover(T objeto){
        Transaction ts = session.beginTransaction();
        session.save(objeto);
        ts.commit();
    }

    public void atualizar(T objeto){
        Transaction ts = session.beginTransaction();
        session.update(objeto);
        ts.commit();
    }

    public T load(long id){
        return (T) session.load(classe, id);
    }
}

Utilizamos na declaração da classe o tipo parametrizado T (de type), indicando que essa classe terá um tipo de Objeto.

No seu construtor, ela receberá um objeto que definirá o tipo usado na classe e utiliza o HibernateUtil para receber uma session. Observe que o método getSession() do Dao genérico é protected pois suas classes filhas precisarão acessa-lo para seus próprios métodos.

Agora criaremos o ClienteDao, que herdará todos os métodos do Dao genérico, sendo assim não será necessário criar os métodos básicos (Salvar, Atualzar, Remover e Carregar).


package Dao;

import java.util.Collection;
import modelo.Cliente;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author lucas
 */
public class ClienteDao extends Dao<Cliente> {

    public ClienteDao(){
        super(Cliente.class);
    }

    public Collection<Cliente> buscaPorNome(String nome){
        Criteria c = getSession().createCriteria(Cliente.class);
        c.add(Restrictions.ilike("nome", nome));
        c.addOrder(Order.asc("idade"));
        return c.list();
    }

    public int qtdeTotalCliente(){
        Criteria c = getSession().createCriteria(Cliente.class);
        c.setProjection(Projections.rowCount());
        return (Integer) c.uniqueResult();
    }

    public int totalSaldo(){
        Criteria c = getSession().createCriteria(Cliente.class);
        c.setProjection(Projections.sum("saldo"));
        return (Integer) c.uniqueResult();
    }
}

Agora conheceremos o poder da API Criteria.
No método buscaPorNome, é recebido como parametro uma String que representa o nome do Cliente a ser buscado.
Em seguida é criado o objeto Criteria, através do método createCriteria() e esse recebe como argumento o tipo de objeto a ser pesquisado, como o objeto está mapeado para uma tabela do banco (eu não demonstrei aqui como mapear, porque como disse não é o objetivo do artigo) a API Criteria já sabe exatamente em qual(is) tabela(s) buscar.
Na linha seguinte utilizamos o método add() para refirnarmos a busca, no nosso caso adicionamos uma restrição através do ilike() do objeto Restrictions e passamos dois parâmetros o primeiro é o campo que será aplicada a restrição e o segundo o valor da restrição. Então no nosso caso informamos que queremos apenas os registros com o campo nome igual ao valor da variável nome.
Para melhorar ainda mais a busca, podemos definir a ordem que os objetos será apresentados. Para isso na linha seguinte usamos o método addOrder() e usamos o objeto Order para definir a ordem, que no nosso caso será o campo idade.
Na linha seguinte é usado o método list() que retorna uma lista de objetos que se encaixa no perfil informado ou null caso não encontre nada.

No método qtdeTotalCliente() é retornado um inteiro com a quantidade total de registro de Clientes salvos no banco. Para isso é utilizado o método setProjection e é passado como parâmetro o que queremos fazer, no caso utilizamos o método rowCount() do Projections para contar a quantidade de registros.
Para finalizar usamos o uniqueResult() para retornar a quantidade de registros.

E para finalizar o artigo, no totalSaldo() estamos utilizando também o setProjection para somar os valores de um determinado campo de todos os registros do banco, para isso utilizamos o método sum() do objeto Projections

Bom, no geral é isso. A API Criteria é muito poderosa, podemos ser utilizada para realizar (quase) todas as queries que você desejar, porém muita gente acha mais rápido e produtivo escrever as queries utilizando a HQL (Hibernate Querie Language) que irei mostrar no próximo artigo.

Categories: Hibernate, Java, SQL Tags: , ,

Hibernate Spatial + Postgis: Uma Introdução

26, dezembro, 2009 10 comentários

Esse tutorial tem como objetivo fazer uma introdução ao uso do Hibernate Spatial juntamente com o banco de dados postgresql e a extensão espacial postgis. Nesse exemplo estarei utilizando o netbeans 6.8.

Para começar, crie um projeto Java no netbeans, clique com o botão direito sobre o projeto e adicione as bibliotecas do “Hibernate” e “Hibernate JPA” ambas disponíveis no netbeans.

Você também irá precisar das seguintes bibliotecas:

Adicione todas as listadas acima ao projeto.

Agora iremos criar o hibernate.cfg.xml, o próprio netbeans fornece um utilitário para criação. Clique com o botão direito no projeto, selecione o menu Novo -> Outro -> Hibernate -> Assistente para configuração do hibernate.

Configure seu hibernate da seguinte maneira:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
    <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
    <property name="hibernate.connection.url">jdbc:postgresql://localhost/teste</property>
    <property name="hibernate.connection.username">postgres</property>
    <property name="hibernate.connection.password">web</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
    <mapping class="modelo.Evento"/>
  </session-factory>
</hibernate-configuration>

Agora iremos criar a classe “Eventos” que será nossa entidade. Ela irá conter o atributo Id que será um inteiro, descrição que será uma string contendo a descrição e o atributo ponto que será do tipo geográfico “Point”.


package modelo;

import com.vividsolutions.jts.geom.Point;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.annotations.Type;

/**
 *
 * @author lucas
 */
@Entity
public class Evento implements Serializable {

    @Id
    @GeneratedValue
    private long id;
    private String descricao;
    @Type(type="org.hibernatespatial.GeometryUserType")
    @Column(columnDefinition="Point")
    private Point ponto;

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Point getPonto() {
        return ponto;
    }

    public void setPonto(Point ponto) {
        this.ponto = ponto;
    }
}

Agora criaremos a classe HibernateUtil, que possuirá um atributo SessionFactory do hibernate, um método que retorne uma Session criada pelo SessionFactory e um bloco de código, todos estáticos. O próprio netbeans possui uma opção de criar automaticamente o HibernateUtil, ela está no mesmo menu que foi usado anteriormente para gerar o arquivo de configuração.

package util;

import org.hibernate.Session;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;

public class HibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static Session getSession() {
        return sessionFactory.openSession();
    }
}

Criaremos agora a classe que irá ler a configuração do hibernate e a partir dos mapeamentos das classes irá gerar automaticamente as tabelas do banco.

package util;

import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

/**
 *
 * @author lucas
 */
public class GeraBanco {

    public static void main(String args[]){

        Configuration conf = new AnnotationConfiguration();
        conf.configure();
        SchemaExport se = new SchemaExport(conf);
        se.create(true, true);
    }
}

O próximo passo é mapear a entidade Evento no hibernate, para isso adicionaremos abaixo do último ‘property’ a linha a seguir:

 <mapping class="modelo.Evento"/>

Deixando o hibernate.cfg.xml da seguinte maneira:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
    <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
    <property name="hibernate.connection.url">jdbc:postgresql://localhost/teste</property>
    <property name="hibernate.connection.username">postgres</property>
    <property name="hibernate.connection.password">web</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
    <mapping class="modelo.Evento"/>
  </session-factory>
</hibernate-configuration>

E por fim iremos trabalhar na classe main:


import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import modelo.Evento;
import org.hibernate.Session;
import org.hibernate.Transaction;
import util.HibernateUtil;

/**
 *
 * @author lucas
 */
public class Main {

    public static void main(String[] args) {

        Evento evento = new Evento();
        evento.setDescricao("Testando");
        Geometry geom = null;
        evento.setPonto((Point) geom);

        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

        session.save(evento);
        tx.commit();
        session.close();
    }
}

Agora rode o GeraBanco para que a tabela do banco seja criada e em seguinda o main. Após fazer isso dê uma conferida no banco e se tiver ocorrido tudo bem o registro estará lá.

Hibernate Spatial

24, julho, 2009 1 comentário

O Hibernate Spatial é uma extensão do famoso framework de persistência Hibernate. Ele faz o mapeamento objeto relacional de tipos de dados geográficos. Para quem trabalha com desenvolvimento de SIG é uma excelente idéia dá uma conferida.
Ele suporta a maioria das funções da OGC (Open Geospatial Consortium) além de suportar também os SGBD Oracle 10g/11g, Postgresql/Postgis, and MySQL.

O site oficial é http://www.hibernatespatial.org/ e para quem trabalha com a plataforma .NET NHibernate

Categories: GIS, Java, SQL Tags: , ,