CloudWare

cafelog-coffee

Minha Classe HibernateUtil

Terça, 03 Janeiro 2012

hibernate

Hoje irei compartilhar minha classe HibernateUtil que fiz e venho usando há algum tempo. Pensando na simplicidade e reutilização do código consegui fazer uma classe utilitária que até hoje vem me servindo muito bem, espero que ajude vocês também.

O quê tem nela?

  • Método para iniciar a SessionFactory
  • Métodos para reiniciar e atualizar o Schema do Banco de Dados
  • Métodos para Selecionar, Inserir, Atualizar e Excluir registros do Banco de Dados genéricos (Servem para QUALQUER POJO)
Todos os métodos contidos na classe HibernateUtil são static. Chega de instâncias!

Confira a classe HibernateUtil:

import java.util.List;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;

public abstract class HibernateUtil {
    private static SessionFactory fabricaSessao;
    private static Session sessao;
    private static Transaction transacao;
    private static Configuration hibernateConfig;
    
    /**
     * Inicia a SessionFactory
     */
    public static void iniciarSessao(){        
        if(hibernateConfig == null)
            try {
                hibernateConfig = new Configuration()
                        .setProperties(getProperties())
                        .addResource("map/pojo1.hbm.xml");
                        .addResource("map/pojo2.hbm.xml");
                        .addResource("map/pojo3.hbm.xml");
            } catch (Exception e){
                System.err.println(e.fillInStackTrace());
            }
        
        if(fabricaSessao == null)
            try {
                fabricaSessao = hibernateConfig.buildSessionFactory();
            } catch (Exception e){
                System.err.println(e.fillInStackTrace());
            }
    }
    
    /**
     * Retorna as propriedades necessárias para inicar a SessionFactory
     * @return Properties
     */
    private static Properties getProperties(){
        Properties prop = new Properties();
        
        prop.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
        prop.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
        prop.setProperty("hibernate.connection.url", "jdbc:mysql://"
             +ConfigUtil.getCfg("SERVIDOR")
             +":"+ConfigUtil.getCfg("PORTA")
             +"/"+ConfigUtil.getCfg("BD"));
        prop.setProperty("hibernate.connection.username", ConfigUtil.getCfg("USUARIO"));
        prop.setProperty("hibernate.connection.password", ConfigUtil.getCfg("SENHA"));
        prop.setProperty("hibernate.show_sql", "true");
        prop.setProperty("hibernate.format_sql", "true");
        prop.setProperty("hibernate.generate_statistics", "true");
        
        return prop;
    }
    
    /**
     * Retorna uma nova sessão
     * @return Session
     */
    private static Session getSessao(){
        return fabricaSessao.openSession();
    }
    
    /**
     * Apaga e cria novamente o Schema do Banco de Dados
     */
    public static void resetarBD(){
        try {
            SchemaExport se = new SchemaExport(hibernateConfig);
            se.drop(true, true);
            se.create(true, true);
        } catch (Exception e) { }
    }
    
    /**
     * Atualiza o Schema do Banco de Dados
     */
    public static void atualizarBD(){
        try {
            SchemaUpdate su = new SchemaUpdate(hibernateConfig);
            su.execute(true, true);
        } catch (Exception e) { }
    }
    
    /**
     * Retorna todos os registros da tabela (classe) informada
     * @param objClass
     * @return List<Object>
     */
    public static List<Object> selecionar(Class objClass){
        List<Object> lista = null;
        Query query = null;
        try {
            sessao = getSessao();
            transacao = sessao.beginTransaction();
            query = sessao.createQuery("From "+objClass.getName());
            lista = query.list();
        } catch (HibernateException e) { 
            transacao.rollback();
            System.err.println(e.fillInStackTrace());
        } finally {
            sessao.close();
            return lista;
        }
    }
    
    /**
     * Retorna apenas um objeto referente a classe e id informados
     * @param objClass
     * @param id
     * @return Object
     */
    public static Object selecionar(Class objClass, long id){
        Object objGet = null;
        try {
            sessao = getSessao();
            transacao = sessao.beginTransaction();
            objGet = sessao.get(objClass, id);
        } catch (HibernateException e) { 
            transacao.rollback();
            System.err.println(e.fillInStackTrace());
        } finally {
            sessao.close();
            return objGet;
        }
    }
    
    /**
     * Persiste o objeto passado por parâmetro
     * @param obj 
     */
    public static boolean inserir(Object obj){
        try{
            sessao = getSessao();
            transacao = sessao.beginTransaction();
            sessao.save(obj);
            transacao.commit();
        } catch (HibernateException e) { 
            transacao.rollback();
            System.err.println(e.fillInStackTrace());
            return false;
        } finally {
            sessao.close();
            return true;
        }
    }
    
    /**
     * Atualiza o objeto passado por parâmetro
     * @param obj 
     */
    public static boolean atualizar(Object obj){
        try{
            sessao = getSessao();
            transacao = sessao.beginTransaction();
            sessao.update(obj);
            transacao.commit();
        } catch (HibernateException e) { 
            transacao.rollback();
            System.err.println(e.fillInStackTrace());
            return false;
        } finally {
            sessao.close();
            return true;
        }
    }
    
    /**
     * Exclui o objeto passado por parâmetro
     * @param obj 
     */
    public static boolean excluir(Object obj){
        try{
            sessao = getSessao();
            transacao = sessao.beginTransaction();
            sessao.delete(obj);
            transacao.commit();
        } catch (HibernateException e) { 
            transacao.rollback();
            System.err.println(e.fillInStackTrace());
            return false;
        } finally {
            sessao.close();
            return true;
        }
    }
}

IMPLEMENTANDO A CLASSE

CONFIGURAÇÃO E SESSIONFACTORY

Vamos começar com a configuração do Hibernate. Nesta classe optei por configurar o Hibernate através da programação e não pelo arquivo XML, isso fica a sua escolha. No método getProperties() setamos o objeto Properties com as devidas configurações (Dialeto, Driver, Usuário e Senha...) e retorna-mos o mesmo.

private static Properties getProperties(){
    Properties prop = new Properties();
    
    prop.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    prop.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");;
    // ...
    prop.setProperty("hibernate.connection.username", ConfigUtil.getCfg("USUARIO"));
    prop.setProperty("hibernate.connection.password", ConfigUtil.getCfg("SENHA"));
    // ...
    
    return prop;
}

Em getProperties() utilizei uma outra classe utilitária minha, o ConfigUtil, que me ajuda a manipular o arquivo de configuração. Brevemente estarei compartilhando-a também.

Em iniciarSessao(), invocamos o getProperties() e continuamos a configurar o Hibernate mapeando as classes (Preferi mapear usando XML e não Annotations).

hibernateConfig = new Configuration()
        .setProperties(getProperties())
        .addResource("map/pojo1.hbm.xml");
        .addResource("map/pojo2.hbm.xml");
        .addResource("map/pojo3.hbm.xml");

Após configurá-lo, construimos nossa SessionFactory (buildSessionFactory()).

fabricaSessao = hibernateConfig.buildSessionFactory();

Ele deve ser chamado logo no inicio da aplicação:

public class Main extends javax.swing.JFrame {
    public Main() {
        initComponents();
        try {
            HibernateUtil.iniciarSessao();
            HibernateUtil.atualizarBD();
        } catch (Exception e) { 
            System.err.println(e.fillInStackTrace()); 
            JOptionPane.showMessageDialog(null, "Erro ao conectar com o Banco de Dados. Configure-o corretamente.", null, JOptionPane.ERROR_MESSAGE);
        }
    }
    
    public static void main(String args[]) {
        new Main().setVisible(true);
    }
}

RESETANDO E ATUALIZANDO O SCHEMA

Chega de DROP TABLE! Utilizando o SchemaExport e SchemaUpdate podemos recriar nosso Banco de Dados e atualizar/sincronizar, respectivamente. Em resetarBD() criamos uma nova instância do SchemaExport e logo em seguida apagamos (drop) e criamos (create) o Schema do Banco de Dados. Exemplo de uso:

private void apagarBanco(){
    HibernateUtil.resetarBD();
}

No atualizarBD() criamos uma nova instância do SchemaUpdate e atualizamos o Schema do Banco de Dados. O que o Hibernate irá fazer aqui é lindo: Ele irá analizar nossos POJOS e o mapeamento e, caso exista alguma novo POJO (tabela) ou atributo (campo) ele irá "sincronizar" com o Banco de Dados. Maravilha não?

Recomendo utilizá-lo logo após chamar o iniciarSessao():

HibernateUtil.iniciarSessao();
HibernateUtil.atualizarBD();

SELECT

Utilizando sobrecarga tenho dois métodos selecionar(), um me retorna uma List<Object> de POJOs e outro apenas um Object (referente ao id passado por parâmetro) que também representa um POJO. Nos dois métodos preciso passar uma Class por parâmetro. Fazendo dessa forma, o método selecionar() (assim como inserir(), atualizar() e excluir()) funcionam com QUALQUER POJO, isso evita de ter que escrever um método para cada POJO onde a estrutura será praticamente a mesma. A implementação deve ser feita da seguinte forma:

// Retornando um List<Object>
List<Pessoa> listaPessoas = (List<Pessoa>) HibernateUtil.selecionar(Pessoa.Class);

// Retornando apenas um Object
Pessoa pessoa = (Pessoa) HibernateUtil.selecionar(Pessoa.Class, 5487);

Utilizei apenas duas sobrecargas para o método selecionar(). Recomendo adicionar novas sobrecargas para suprir eventuais necessidades.

INSERT, UPDATE E DELETE

Continuando com o CRUD, agora vou demonstrar como utilizar os métodos inserir(), atualizar() e excluir(). A idéia é similar ao método selecionar(). Nos três métodos iremos passar um Object por parâmetro que representa o POJO. Novamente temos métodos genéricos que substituem métodos como inserirPessoa(Pessoa p), inserirFuncionario(Funcionario f), inserirCargo(Cargo c)... Vamos ao exemplo:

// INSERT
HibernateUtil.inserir(pessoa);
HibernateUtil.inserir(funcionario);
HibernateUtil.inserir(cargo);

// UPDATE
HibernateUtil.atualizar(pessoa);
HibernateUtil.atualizar(funcionario);
HibernateUtil.atualizar(cargo);

// DELETE
HibernateUtil.excluir(pessoa);
HibernateUtil.excluir(funcionario);
HibernateUtil.excluir(cargo);

Lembrando que tanto para atualizar quanto para excluir um registro é necessário que a chave primária tenha um valor definido.

CONCLUSÃO

A dica foi dada. Espero que sirva como modelo para quem esta iniciando com o Hibernate ou busca uma classe utilitária simples e completa. Sintam-se a vontade para implementar novas funcionalidades e, se possível, compartilhem. Usem com moderação Yell

Android

Java

Hibernate

Joomla!

CSS3

HTML5

Saia na Frente

html5 css3

Sobre Mim

sobre-foto-2Adriel Café é Web Master e Desenvolvedor Java. Ele incentiva o uso/estudo de Web Standards, Java e Android.

Saiba Mais

Encontre-me

facebook linkedin